2017-10-19 52 views
0

我正在使用HOC組件來限制對未登錄用戶的路由訪問。這個HOC重新掛載子組件時掛載或重新呈現時,直接從url訪問此路線(在應用程序第一次加載時)的問題。例如,我在PaperWorkProgress組件中有3次did mount路由授權HOC導致重新安裝兒童3次

路由定義:

<Route path="/paperwork/progress" component={RequireAuth(PaperWorkProgress)}/> 

這裏HOC代碼:

import React, {Component} from 'react'; 
import {connect} from 'react-redux'; 

export default function(ComposedComponent) { 
    class Authentication extends Component { 

    // check if token exists in storage 
    componentWillMount() { 
     const token = localStorage.getItem('token'); 
     if (!token) { 
     const {pathname, search} = this.props.location; 
     this.props.history.push({ 
      pathname: '/signin', 
      search: `?redirect_to=${pathname}${search}`, 
     }); 
     } 
    } 

    // additional check 
    componentWillUpdate(nextProps) { 
     if (!nextProps.loggedIn) { 
     const {pathname, search} = this.props.location; 
     this.props.history.push({ 
      pathname: '/signin', 
      search: `?redirect_to=${pathname}${search}`, 
     }); 
     } 
    } 

    render() { 
     return <ComposedComponent {...this.props} />; 
    } 
    } 

    function mapStateToProps(state) { 
    return {loggedIn: state.session.loggedIn}; 
    } 

    return connect(mapStateToProps)(Authentication); 
} 

任何想法?

+0

嘗試把它'componentDidMount' – Dane

+0

我在細節上如何一個auth HOC可以用在刀刃上解釋這裏:https://stackoverflow.com/questions/46379934/react-router-v4-authorized-routes-and-components –

+0

@MatthewBarbara我的HOC基於你的解決方案,但沒有上下文功能。 – Kort

回答

0

我不確定這會對重新渲染問題產生影響,但是您的代碼感覺不對。

首先,你似乎有2個真相源,你的redux商店和localStorage,這使事情變得複雜。如果您想從之前的導航信息中「保存」商店,則應使用createStore「preloadedState」參數,而不是每次都在組件中進行檢查。 Cf Redux doc和Redux自己的創作者的視頻Video for persisting and rehydrating State。一旦你的狀態只來自你的商店,它開始變得更加簡單。

其次,

當你推到組件裏面的歷史記錄對象,感覺就像你是變異的組件自己的道具(如歷史是一個道具)。這對我來說很奇怪,可能是你問題的根源。

爲什麼不使用像這樣的渲染方法中的重定向組件? cf React router docs。組件將看起來像這樣(很明顯,你需要在文檔中改變你的登錄組件太像)

import React, { Component } from "react"; 
import { connect } from "react-redux"; 
import { Redirect } from "react-router-dom"; 

export default function(ComposedComponent) { 
    class Authentication extends Component { 
    render() { 
     return !this.props.loggedIn ? (
     <Redirect 
      to={{ 
      pathname: "/login", 
      state: { from: this.props.location } 
      }} 
      {...this.props} 
     /> 
    ) : (
     <ComposedComponent {...this.props} /> 
    ); 
    } 
    } 

    function mapStateToProps(state, ownProps) { 
    return { loggedIn: state.session.loggedIn, ...ownProps }; 
    } 
    return connect(mapStateToProps)(Authentication); 
} 
+0

我使用的是localStorage,因爲在應用程序中第一次加載'state.session.loggedIn'仍然不存在並且只在'refresh token'動作後填充,並且它總是進行重定向。 – Kort