当状态改变时,React-router-dom不会重新渲染Switch [英] React-router-dom not re rendering Switch when state is change

查看:77
本文介绍了当状态改变时,React-router-dom不会重新渲染Switch的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using aws-amplify, react-hook in my project. The app have some private Routes has been define below:

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没有被渲染.

In App.js, we change childProps to define whether user is login or not. But when childProps change, Switch not re rendering. What is the way to force React re rendering its Route because isAuthenticated is change but ProtectedRoute is not rerender.

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>)

推荐答案

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

The route only renders again when you enter that URL again. You are doing a Redirect, meaning it will never have a chance to enter the same URL after authentication is complete. You should delay rendering the protected route until you have confirmed authentication:

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
                            }`}
                    />
                )
            }
        />
    );
}

这篇关于当状态改变时,React-router-dom不会重新渲染Switch的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆