繁体   English   中英

ReactJS:如果在承诺解决后进行身份验证,则呈现私有路由

[英]ReactJS: render private route if authenticated after promise resolved

我有这个PrivateRoute功能组件,它决定渲染组件,该组件作为他有权访问的用户的道具传递,基于他的身份验证或重定向到未经授权的路由。

isValidToken是一个异步函数,检查用户是否具有有效令牌,并返回一个分配给isUserLogged布尔值。所以当我在useEffect钩子中调用这个函数时,它等待函数解析但在完成重定向之前发生。 那么我如何等待直到它在承诺解决之前根据该值解决和呈现?

import React, { useState, useEffect } from "react";
import { Route, Redirect } from "react-router-dom";
import isValidToken from "../utils/isValidToken";

const ProtectedRoute = ({ component: Comp, path, redirectto, ...rest }) => {
  const [isloggedin, setloggedin] = useState(false);

  useEffect(() => {
    (async function() {
      const isUserLogged = await isValidToken();
      setloggedin(isUserLogged);
    })();
  }, []);

  return (
    <Route
      path={path}
      {...rest}
      render={props => {
        return isloggedin ? (
          <Comp {...props} />
        ) : (
          <Redirect to={redirectto} />
          // <h1>404 error</h1>
        );
      }}
    />
  );
};

export default ProtectedRoute;

为了避免过早的重定向,您的组件需要考虑承诺的“挂起状态”(在异步函数调用之后)。

在挂起(或“加载”)状态期间,您通常会呈现诸如加载微调器之类的东西,以向用户表明应用程序正忙。 关键是在 promise 被解析(或拒绝)之前不要渲染<Comp /><Redirect />组件:

 import React, { useState, useEffect } from "react"; import { Route, Redirect } from "react-router-dom"; import isValidToken from "../utils/isValidToken"; const ProtectedRoute = ({ component: Comp, path, redirectto, ...rest }) => { /* Track the state of your app instead. Start with a "loading" state */ const [state, setState] = useState('loading'); useEffect(() => { (async function() { try { /* Update effect logic to track correct state */ const isUserLogged = await isValidToken(); setState(isUserLogged ? 'loggedin' : 'redirect'); } catch { setState('redirect'); } })(); }, []); /* If in loading state, return loading message while waiting for isValidToken to complete */ if(state === 'loading') { return <div>Loading..</div> } return ( <Route path={path} {...rest} {/* Decide what component to render based on state */ render={props => ((state === 'loggedin') ? <Comp {...props} /> : <Redirect to={redirectto} />) } /> ); }; export default ProtectedRoute;

尝试这个:

import React, { useState, useEffect } from "react";
import { Route, Redirect } from "react-router-dom";
import isValidToken from "../utils/isValidToken";

const ProtectedRoute = ({ component: Comp, path, redirectto, ...rest }) => {
  const [isloggedin, setloggedin] = useState(false);

  const [redirectTo, setRedirectTo] = useState(null);

  useEffect(() => {
    (async function() {
      const isUserLogged = await isValidToken();
      setloggedin(isUserLogged);
      setRedirectTo('/route');
    })();
  }, []);

  if (redirectTo && isloggedin) {
      return <Redirect to={redirectTo} />
  }

  return (
    <Route
      path={path}
      {...rest}
      render={props => <Comp {...props} />}
    />
  );
};

export default ProtectedRoute;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM