如何使用 React hooks 和 react-router 执行身份验证 [英] How to perform authentication with React hooks and react-router

查看:32
本文介绍了如何使用 React hooks 和 react-router 执行身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 react-router-domreact hooks 对每次路由更改的用户进行身份验证.这个想法是,每次用户导航到一条路线时,系统都会进行 api 调用并验证用户的身份.我需要实现这一点,因为我使用 react-redux,并且在每个窗口重新加载时,redux 状态不会持久化.所以我需要再次将 isLoggedNow 道具设置为 true:

const PrivateRoute = ({组件:组件,checkOnEachRoute: checkReq,是用户登录,...休息}) =>{const [isLoggedNow, setLogged] = useState(isUserLogged);使用效果(() =>{const fetchStatus = async() =>{尝试 {等待 selectisUserLogged();设置记录(真);} 捕捉(错误){控制台日志(错误);}};fetchStatus();},[isUserLogged],);返回 (<路线{...休息}渲染={道具=>是LoggedNow 吗?(<div><组件{...道具}/>

) : (<重定向到={{路径名:'/登录',}}/>)}/>);};

然后我会像这样使用上面的 PrivateRoute:

function App(props) {返回 (<div><切换位置={props.location}><路由精确路径="/login" component={Login}/><PrivateRoute 精确路径="/sidebar" component={Sidebar}/></开关>

);}

首先 isUserLoggedtrue,但在窗口重新加载后,我收到一个错误 警告:无法在未安装的组件上执行 React 状态更新.那么我怎样才能做到这一点,所以在每个窗口重新加载时我都会对用户进行身份验证?我正在寻找某种 componentWillMount.

解决方案

类似这样的事情(其中 isUserLogged 是来自 redux 的道具):

function PrivateRoute({ component: Component, isUserLogged, ...rest }) {const [isLoading, setLoading] = useState(true);const [isAuthenticated, setAuth] = useState(false);useEffect(() => {const fetchLogged = async() =>{尝试 {设置加载(真);const url = 新 URL(fetchUrl);const fetchedUrl = 等待 fetchApi(url);setAuth(fetchedUrl.body.isAllowed);设置加载(假);} 捕捉(错误){设置加载(假);}};fetchLogged();}, []);返回 (<路线{...休息}渲染={道具=>//eslint-disable-next-line no-nested-ternaryisUserLogged ||已认证?(<组件{...道具}/>) : 正在加载?(<旋转尺寸=大"/>) : (<重定向到={{路径名:'/登录',}}/>)}/>);}

I am trying to authenticate user on each route change with react-router-dom and react hooks. The idea is that each time user navigates to a route the system makes an api call and authenticate the user. I need to achieve this because I use react-redux, and on each window reload the redux state is not persisted. So i need to set the isLoggedNow prop to true again:

const PrivateRoute = ({
  component: Component,
  checkOnEachRoute: checkReq,
  isUserLogged,
  ...rest
}) => {
  const [isLoggedNow, setLogged] = useState(isUserLogged);
  useEffect(
    () => {
      const fetchStatus = async () => {
        try {
          await selectisUserLogged();
          setLogged(true);
        } catch (error) {
          console.log(error);
        }
      };
      fetchStatus();
    },
    [isUserLogged],
  );
  return (
    <Route
      {...rest}
      render={props =>
        isLoggedNow ? (
          <div>
            <Component {...props} />
          </div>
        ) : (
          <Redirect
            to={{
              pathname: '/login',
            }}
          />
        )
      }
    />
  );
};

I then would use the above PrivateRoute like this:

function App(props) {
  return (
    <div>
      <Switch location={props.location}>
        <Route exact path="/login" component={Login} />
        <PrivateRoute exact path="/sidebar" component={Sidebar} />
      </Switch>
    </div>
  );
}

First the isUserLogged is true, but after window reload I get an error Warning: Can't perform a React state update on an unmounted component. So how can I achieve this, so on each window reload I authenticate the user? I am looking for some kind of componentWillMount.

解决方案

Something like this works (where isUserLogged is a prop from redux):

function PrivateRoute({ component: Component, isUserLogged, ...rest }) {
  const [isLoading, setLoading] = useState(true);
  const [isAuthenticated, setAuth] = useState(false);
  useEffect(() => {
    const fetchLogged = async () => {
      try {
        setLoading(true);
        const url = new URL(fetchUrl);
        const fetchedUrl = await fetchApi(url);
        setAuth(fetchedUrl.body.isAllowed);
        setLoading(false);
      } catch (error) {
        setLoading(false);
      }
    };
    fetchLogged();
  }, []);
  return (
    <Route
      {...rest}
      render={props =>
        // eslint-disable-next-line no-nested-ternary
        isUserLogged || isAuthenticated ? (
          <Component {...props} />
        ) : isLoading ? (
          <Spin size="large" />
        ) : (
          <Redirect
            to={{
              pathname: '/login',
            }}
          />
        )
      }
    />
  );
}

这篇关于如何使用 React hooks 和 react-router 执行身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆