【问题标题】:Flash of protected route's content with React Router 6使用 React Router 6 刷新受保护路由的内容
【发布时间】:2022-08-08 14:10:29
【问题描述】:

当使用React Router 6 创建“受保护路由”时,我看到受保护页面的内容在重定向到登录页面之前短暂闪烁。

我认为这一定是一个众所周知的问题。有解决方案吗?

保护路线:

const ProtectedRoute = ({
    redirectPath = \'/login\',
    children
}) => {

    const { user } = UserAuth();

    if (!user) {
        return <Navigate to={redirectPath} replace />;
    }

    return children
        ? children
        : <Outlet />;
};

export default ProtectedRoute;

应用路由器:

const AppRouter = () => (
    <Routes>

        <Route path=\"/\" element={<LoginPage />} />
        <Route path=\"login\" element={<LoginPage />}/>

        <Route element={<ProtectedRoute />} >
            <Route path=\"account\" element={<AccountPage />} />
        </Route>

    </Routes>
);

export default AppRouter;

    标签: javascript reactjs react-router react-router-dom


    【解决方案1】:

    我会假设UserAuth() 会执行一些异步任务,在这种情况下,您会得到这种行为是正常的。您可以使用加载状态来显示加载器。我假设您可以在执行身份验证代码时从UserAuth() 获得一个。像这样:

    const ProtectedRoute = ({
        redirectPath = '/login',
        children
    }) => {
    
        const { user, loading } = UserAuth();
        
        if (loading) return <div>Loading...</div>
    
        if (!user) {
            return <Navigate to={redirectPath} replace />;
        }
    
        return children
            ? children
            : <Outlet />;
    };
    
    export default ProtectedRoute;
    

    【讨论】:

    • 谢谢,问题是最初user 设置为{}。大约一秒钟左右后,它才被设置为实际的用户对象。
    • 很高兴我能给出一个提示@Ben :)
    【解决方案2】:

    问题

    问题是要为用户提供适当的 UI/UX,您需要 3 个状态(即经过身份验证的,未经身份验证的,不确定的) 而不是 2 (已认证和未认证)。如果只有 2 个状态,则初始身份验证值和分支逻辑匹配其中一个,并错误地“泄漏”受保护的内容片刻或过早地重定向到登录路由。

    解决方案

    使用不确定的user 值或加载状态向受保护的路由组件指示它不应该呈现受保护的内容或重定向。

    使用第三个不确定的“状态”。

    例如,如果经过身份验证的 user 值是用户目的并且未经身份验证的user 值为null,然后使用undefined 作为不确定值,并在解决身份验证状态时有条件地呈现空值或某些加载指示符。

    const ProtectedRoute = ({
      redirectPath = '/login',
      children
    }) => {
      const { user } = userAuth();
    
      if (user === undefined) {
        return null; // or loading spinner, etc
      }
    
      if (!user) {
        return <Navigate to={redirectPath} replace />;
      }
    
      return children
        ? children
        : <Outlet />;
    };
    

    使用挂起/加载“状态”。

    有时只为userAuth 状态添加加载状态很有用。逻辑几乎相同。

    const ProtectedRoute = ({
      redirectPath = '/login',
      children
    }) => {
      const { isLoading, user } = userAuth();
    
      if (isLoading) {
        return null; // or loading spinner, etc
      }
    
      if (!user) {
        return <Navigate to={redirectPath} replace />;
      }
    
      return children
        ? children
        : <Outlet />;
    };
    

    【讨论】:

      猜你喜欢
      • 2018-08-11
      • 2022-11-27
      • 2020-10-26
      • 1970-01-01
      • 2021-12-20
      • 2022-07-30
      • 2021-12-05
      • 2018-05-24
      • 2021-11-03
      相关资源
      最近更新 更多