reactjs - 使用react。具有异步获取请求的私有(private)路由器

标签 reactjs authentication asynchronous routing fetch

我在我的应用程序中使用带有 thunk 的 react 路由器 v4 进行路由。
我想阻止渲染 <AccountPage />组件给未登录的用户。我在服务器上发送带有 id 和 token 的 fetch 请求以 checkin 数据库,用户是否有此 token 。如果有 - 渲染 <AccountPage /> ,如果不是 - 重定向回家。

我不明白什么是实现“条件路由”的好方法,我发现一些似乎几乎完全适合我的任务的东西。https://gist.github.com/kud/6b722de9238496663031dbacd0412e9d
但问题是 condition<RouterIf />总是未定义的,因为 fetch 是异步的。我处理这个异步的尝试没有任何结果或错误:

Objects are not valid as a React child (found: [object Promise]) ...

或者
RouteIf(...): Nothing was returned from render. ...

这是代码:
//RootComponent
<BrowserRouter>
    <Switch>
        <Route exact path='/' component={HomePage}/>
        <Route path='/terms' component={TermsAndConditionsPage}/>
        <Route path='/transaction(\d{13}?)' component={TransactionPage}/>
        <RouteIf
            condition={( () => {
                if( store.getState().userReducer.id, store.getState().userReducer.token) {


                    // Here i sending id and token on server 
                    // to check in database do user with this id
                    // has this token
                    fetch(CHECK_TOKEN_API_URL, {
                        method: 'post',
                        headers: {'Accept': 'application/json', 'Content-Type': 'application/json'},
                        body: JSON.stringify({
                            id: store.getState().userReducer.id,
                            token: store.getState().userReducer.token
                        })
                    })


                    .then res => {
                        // If true – <RouteIf /> will render <AccountPage />, 
                        // else - <Redirect to="/"> 
                        // But <RouteIf /> mounts without await of this return 
                        // You can see RouteIf file below
                        if(res.ok) return true
                        else return false
                    })


                }
            })()}
            privateRoute={true}
            path="/account"
            component={AccountPage}
        />
    </Switch>
</BrowserRouter>




//RouteIf.js
const RouteIf = ({ condition, privateRoute, path, component }) => {
    // The problem is that condition is 
    // always undefined, because of fetch's asyncronosly
    // How to make it wait untill
    // <RouteIf condition={...} /> return result?
    return condition 
    ? (<PrivateRoute path={path} component={component} />)
    :(<Redirect to="/" />)
}

export default RouteIf

制作方法condition等到fetch返回答案?或者也许还有另一种更好的方法来检查用户是否登录?

最佳答案

如果您使用的是 redux,您可以显示临时的“正在加载...” View 。仅当用户为 null 并已加载时,才会重定向路由。

PrivateRoute.js

import React from 'react';
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';

import { Route, Redirect } from 'react-router-dom';

import { selectors } from 'settings/reducer';

const PrivateRoute = ({ component: Component, ...rest }) => {
  const user = useSelector(state => selectors.user(state));
  const isLoaded = useSelector(state => selectors.isLoaded(state));

  return (
    <Route
      {...rest}
      render={props =>
        !isLoaded ? (
          <></>
        ) : user ? (
          <Component {...props} />
        ) : (
          <Redirect to='/sign_in' />
        )
      }
    />
  );
};

export default PrivateRoute;

PrivateRoute.propTypes = {
  component: PropTypes.any
};

路由.js
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import PrivateRoute from './components/PrivateRoute';

export const Routes = () => (
  <BrowserRouter>
    <Switch>
      <Route exact={true} path='/' component={Home} />
      <PrivateRoute path='/account' component={Account} />
    </Switch>
  </BrowserRouter>
);

关于reactjs - 使用react。具有异步获取请求的私有(private)路由器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49309071/

相关文章:

javascript - 在更新期间管理 React 组件行为

authentication - 使用 Vanilla 论坛使用 Cookie 对用户进行身份验证

javascript - 如何使用 async/await 方法将对象传递到 phantom js 页面?

javascript - 如何解决 Typescript 中关于 `withStateHandlers` 的错误

reactjs - 通过 ESLint 版本在 vscode 上启动 React 应用程序失败

javascript - 编译时出现 graphQL 错误

postgresql - 当添加两个或更多权限条件时,Hasura 查询变得指数级变慢

php - Mysqli 上的 Php 登录注销脚本问题

c++ - 我可以精确地时间重叠 ReadFileEx 操作吗?

java - 服务中的 Spring @Async 方法