首页 > 解决方案 > 带异步的 React-router-dom 保护路由

问题描述

所以,我有以下路由器:

 <Router>
   <TopBar />
     <Route path="/" exact component={Home} />
     <Route path="/cadastro" exact component={SignUp} />
     <Route path="/login" exact component={Login} />
     <ProtectedRoute path="/perfil/:profileId" auth={props.auth} exact component={Profile} />
   <Footer />
 </Router>

/perfil/:profileId必须仅为经过身份验证的用户保护路由。我的 ProtectedRoute 组件如下所示:

function ProtectedRoute({
  component: Component,
  dispatch,
  auth,
  ...rest
}) {
  return (
    <Route
      {...rest}
      render={props =>
        isAuthenticated() ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/login",
            }}
          />
        )
      }
    />
  );
}

根据isAuthenticated()结果​​,它决定用户是否访问该页面。我的问题是该isAuthenticated()函数向服务器发出请求以验证身份验证令牌,因此它是异步的。我不能只在我的 isAuthenticated 函数中放置一个 async/await,因为会出现以下错误:

Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.

有人对如何解决这个问题有任何想法吗?我所有的身份验证逻辑都在服务器端,(对我来说)为了解决这个问题而只在客户端保留验证逻辑是没有意义的。谢谢 :)

标签: reactjsauthenticationasynchronousasync-awaitreact-router-dom

解决方案


我建议做的是创建一个这样的函数:

 const renderContent = () => {
        switch (props.auth) {
            case false:
                return (
                    <Switch>
                         <Route path="/" exact component={Home} />
                         <Route path="/cadastro" exact component={SignUp} />
                         <Route path="/login" exact component={Login} />
                         <Redirect to={{ pathname: "/login" }} />
                    </Switch>
                );
            default:
                return (
                    <Switch>
                       <Route path="/" exact component={Home} />
                       <Route path="/cadastro" exact component={SignUp} />
                       <Route path="/login" exact component={Login} />
                       <Route path="/perfil/:profileId" exact component={Profile} />
                       <Redirect to={{ pathname: "/" }} />
                    </Switch>
                );
        }
    };

然后在您的渲染方法中,您可以这样做:

 return <div>{renderContent()}</div>;

推荐阅读