首页 > 解决方案 > React Router 和 redux auth token 双重渲染

问题描述

所以我正在使用redux,如果用户登录则调度一个令牌。然后我获取用户的令牌,如果它存在,我设置X路由可用,否则,Y路由。问题是每次刷新时,App 组件都会渲染两次。第一次是令牌,null第二次是令牌true

好吧,为什么要渲染两次?如果您认为它比这更有效,请用不同的方法来回答相同的操作。

请,如果您需要更多代码,请询问。

问候

代码:

const App = () => {
    const dispatch = useDispatch();
    const token = useSelector((state) => state.auth.token);
    const onCheckAuth = useCallback(() => dispatch(checkAuth()), [dispatch]);

    useEffect(() => {
        onCheckAuth();
    }, [onCheckAuth]);

    const render = () => {
        if (token) {
            return (
                <Switch>
                    <Route path='/hearing' component={Hearing} />
                    <Route path='/logout' component={Logout} />
                    <Route path='/' exact component={Dashboard} />
                    <Redirect to='/' />
                </Switch>
            );
        }

        return (
            <Switch>
                <Route path='/login' component={Login} />
                <Redirect to='/login' />
            </Switch>
        );
    };

    console.log(token);

    return <>{render()}</>;
};

export default App;

标签: javascriptreactjsroutesreact-router

解决方案


首先,我会简单解释一下为什么它会被渲染两次。

当应用程序第一次加载时,redux 具有初始状态并且应用程序调度 checkAuth 操作。这是第一次渲染。

一旦 checkAuth 被调度,redux 的状态将被更新并导致另一个渲染。

这就是为什么它被渲染两次。

然后我会解释如何在react App中处理token。

您应该将令牌保存在浏览器的本地存储中,而不是在 redux 中。

因此,当应用程序首次加载时,必须检查本地存储中的令牌是否存在和过期。然后就可以将token保存到redux中与token更新同步了。如果它是无效的令牌,那么您需要刷新一个新的令牌。

最后使用功能组件,您不需要定义 render() 方法。

应该直接退货。

const App = () => {
    const dispatch = useDispatch();
    const token = useSelector((state) => state.auth.token);
    const onCheckAuth = useCallback(() => dispatch(checkAuth()), [dispatch]);

    useEffect(() => {
        onCheckAuth();
    }, [onCheckAuth]);

    if (token) {
        return (
            <Switch>
                <Route path='/hearing' component={Hearing} />
                <Route path='/logout' component={Logout} />
                <Route path='/' exact component={Dashboard} />
                <Redirect to='/' />
            </Switch>
        );
    } else {
        return (
            <Switch>
                <Route path='/login' component={Login} />
                <Redirect to='/login' />
            </Switch>
        );
    }
};

export default App;

推荐阅读