Redux状态更新时,受保护的路由器不会重新呈现

时间:2020-08-26 05:38:19

标签: javascript reactjs api redux router

我正在尝试使用受保护的路由来防止未经身份验证的用户看到页面。为此,每次页面重新加载时,我都会连接到服务器以检查令牌,并查看是否经过了用户身份验证,并在服务器响应时更新了Redux状态。这可以正常工作,但是当我尝试更新“受保护的路由”组件时出现了问题。由于服务器响应的延迟,组件第一次使用默认状态值false进行渲染,但是当我获得服务器响应并将Redux状态更新为true时,组件不会重新渲染

function ProtectedRoute(props, {component: Component, ...rest}){
    return (
        <Route 
            {...rest}
            render={props =>{
               if(props.userLoginStatus){
                    console.log('protected if')
                    return <Component {...props} />
                } else {
                    console.log('protected else')
                    return <Redirect to={{
                        pathname: '/forbidden',
                        state: {from: props.location}
                    }}
                    />
                }
            }}
        />
    )
}

const mapStateToProps = (state) => {
    return {
        userLoginStatus: state.userLoginReducer.userLogin
    }
}

export default connect(mapStateToProps)(ProtectedRoute)

3 个答案:

答案 0 :(得分:0)

也许您可以使用以下“ browserHistory”进行重定向。

import { browserHistory } from 'react-router'

// ...
else {
       console.log('protected else')
       return browserHistory.push('/forbidden');
     }

答案 1 :(得分:0)

我也有类似的问题。

首先,您需要调度一个操作,以检查在呈现商店之后用户是否已通过身份验证。

由于身份验证验证似乎是一个异步过程,因此您可能要发送两个操作:import React, {useEffect} from 'react' import CircleType from 'circletype' function RotatingCircle() { // const circleOfSkills = new CircleType(document.getElementById('rounded-text')) // .radius(100) // useEffect(() => { // return () => circleOfSkills.mount() // }, [circleOfSkills]) return ( <p className="circle" id="rounded-text"> AND THE WORLD KEEPS GOING AROUND AND AROUND AND AROUND </p> ) } export default RotatingCircle (在商店首先呈现时)和auth_verification_request(在成功验证身份时)。

然后,将使用auth_verification_success函数将更新后的状态发送到您的ProtectedRoute。之后,您的组件应在身份验证状态更新后重新呈现。

我将向您展示一些示例。

authActions.js

mapStateToProps

您的export const verifyAuth = () => { return ((dispatch) => { // auth verification requested dispatch({ type: 'VERIFY_REQUEST' }) // signin request dispatch({ type: 'SIGN_IN_REQUEST' }); // check if user is logged in or not if (logged_in) { // signin success dispatch({ type: 'SIGN_IN_SUCCESS' }) // auth verification success dispatch({ type: 'VERIFY_SUCCESS' }) } // if not logged in else { // auth verification rejected dispatch({ type: 'VERIFY_ERROR' }) } } } 应该看起来像这样:

ProtectedRoute.js

ProtectedRoute

当您使用这些组件时,请确保将const ProtectedRoute = ({ component: Component, isAuthenticated, isVerifying, ...rest }) => { return ( <Route { ...rest } render={ props => isVerifying ? ( <div /> ) : isAuthenticated ? ( <Component { ...props } /> ) : ( <Redirect to={ { pathname: 'REDIRECT_PATH', state: { from: props.location } } } /> ) } /> ) }; isAuthenticated变量传递给isVerifying。像这样:

Router.js

ProtectedRoute

如果您对我的代码有疑问,请告诉我。

答案 2 :(得分:0)

根据this post,解决方案是向组件添加if语句,以渲染加载,直到组件从服务器得到答案为止。因此,我将默认操作值从false更改为null并添加了if语句。在我的代码中,它看起来像这样:

function ProtectedRoute({component: Component, isAuth, ...rest}){

    //Whaiting until gets response from server
    if (isAuth === null) {
        return 'loading..'
    }
    
    return (
        <Route 
            {...rest}
            render={(props) => {
                if(isAuth){
                    console.log('protected if')
                    return <Component {...props} />
                } else {
                    return <Redirect to={{
                        pathname: '/forbidden',
                        state: {from: props.location}
                    }}
                    />
                }
            }}
        />
    )
}

const mapStateToProps = (state) => {
    return {
        isAuth: state.userLoginReducer.userLogin
    }
}

export default connect(mapStateToProps)(ProtectedRoute)

我不确定是解决这个问题的最佳方法,但似乎可以解决我的头痛。