反应上下文和认证路由

时间:2020-08-01 17:45:25

标签: reactjs react-router react-context

我试图使用React和Typescript实现身份验证路由,但是我偶然发现了一个特殊的用例。对于客户端浏览,一切正常,但是,当我在浏览器上手动更改路由时,上下文会稍后更新(一旦重定向了路由),并且PrivateRoute组件中没有进一步的渲染。

为避免此问题,我添加了一个isRendered标志以确保在显示路由之前清楚地描述了该状态(将isLoggedIn标志设置为true),但是,我想知道潜在原因并在可能的情况下提供更干净的解决方案。

我的应用上下文

import React, { createContext, useState, useEffect } from 'react';
import { DEFAULT_APP_STATE } from 'utils/constants';
import { AppState, AppContextProps } from 'types';
import Cookies from 'universal-cookie';

const AppContext = createContext<AppState>(DEFAULT_APP_STATE);

const AppContextProvider: React.FunctionComponent<AppContextProps> = ({
  children,
}) => {
  const [username, setUsername] = useState<string>('');
  const [userToken, setUserToken] = useState<string>('');
  const [isSignedIn, setIsSignedIn] = useState<boolean>(false);
  const [isRendered, setIsRendered] = useState<boolean>(false);
  //effect that will ensure the login state after refresh
  useEffect(() => {
    const cookies = new Cookies();
    const cookieUser = cookies.get('username');
    const cookieToken = cookies.get('userToken');
    if (cookieUser && cookieToken) {
      setUsername(cookieUser);
      setUserToken(cookieToken);
      setIsSignedIn(true);
    }
    setIsRendered(true);
  }, []);
  return (
    <AppContext.Provider
      value={{
        username,
        userToken,
        setUsername,
        setUserToken,
        isSignedIn,
        setIsSignedIn,
      }}
    >
      {isRendered && children}
    </AppContext.Provider>
  );
};

export default AppContextProvider;
export const useAppContext = () => React.useContext(AppContext);

私人路线:

import React from 'react';
import { useAppContext } from './App/AppContext';
import { Redirect, Route, RouteProps } from 'react-router-dom';
import { ROUTES } from 'utils/constants';

const PrivateRoute: React.FunctionComponent<RouteProps> = routeProps => {
  const { isSignedIn } = useAppContext();
  return isSignedIn ? <Route {...routeProps} /> : <Redirect to={ROUTES.HOME} />;
};

export default PrivateRoute;

0 个答案:

没有答案