当状态改变时,React-router-dom不重新渲染Switch

时间:2020-05-23 04:54:41

标签: reactjs routes react-router-dom react-apollo aws-amplify

我在项目中使用aws-amplify,react-hook。该应用程序有一些私人路线已在下面定义:

const ProtectedRoute = ({render: C, props: childProps, ...rest}) => {  
    return (
        <Route
            {...rest}
            render={rProps =>
                (childProps) ? (
                    <C {...rProps} {...childProps} />
                ) : (
                    <Redirect
                        to={`/login?redirect=${rProps.location.pathname}${
                            rProps.location.search
                            }`}
                    />
                )
            }
        />
    );

}

在App.js中,我们更改 childProps 来定义用户是否登录。但是,当 childProps 更改时,Switch不会重新呈现。强制React重新呈现其Route的方法是什么,因为isAuthenticated是已更改,但ProtectedRoute没有被呈现。

const [isAuthenticated, userHasAuthenticated] = useState(null);
    useEffect(() => {
        onLoad();
    }, []);


    async function onLoad() {
        try {
            let user = await Auth.currentSession();
            if (user.accessToken.payload) {
                userHasAuthenticated(user.accessToken.payload);
            }
        } catch (e) {
            if (e !== 'No current user') {
                alert(e);
            }
        }

    }
.....
 const childProps = isAuthenticated;
 return (
 <ApolloProvider client={client} >
            <div className="App">
                <BrowserRouter>
                    <Route path='/'>
                        <div>
                            <Switch>


                                <Route path='/login' render={props => <Login {...props}/>} exact/>
                                 <ProtectedRoute
                                    exact
                                    path='/admin/:name'
                                    render={()=> <Admin  />}
                                    props={childProps}
                                />



                                <Route path='/' render={props => <User {...props} />}/>

                            </Switch>
                        </div>
                    </Route>
                </BrowserRouter>
            </div>
        </ApolloProvider>)

1 个答案:

答案 0 :(得分:2)

仅当您再次输入该URL时,路由才会再次呈现。您正在执行重定向,这意味着在身份验证完成后它将永远没有机会输入相同的URL。您应该延迟渲染受保护的路由,直到您确认身份验证为止:

useEffect(() => {
    async function onLoad() {
        try {
            let user = await Auth.currentSession();
            userHasAuthenticated(!!user.accessToken.payload);
        } catch (e) {
            if (e !== 'No current user') {
                alert(e);
            }
        }

    }
    onLoad();
}, []);
...
const ProtectedRoute = ({render: C, props: childProps, ...rest}) => {  
    if (childProps === null) {
        // app still waiting authentication
        return 'Loading...';
    }

    return (
        <Route
            {...rest}
            render={rProps =>
                (childProps) ? (
                    <C {...rProps} {...childProps} />
                ) : (
                    <Redirect
                        to={`/login?redirect=${rProps.location.pathname}${
                            rProps.location.search
                            }`}
                    />
                )
            }
        />
    );
}