【问题标题】:React context undefined when refreshing page刷新页面时反应上下文未定义
【发布时间】:2021-01-10 15:13:07
【问题描述】:

我想创建一个只有经过身份验证的用户才能访问的受保护路由。 BUT 当我刷新页面时,上下文未定义并将用户重定向到登录页面。我真的不明白为什么会这样。

刷新页面后的控制台日志

App.js

import React, { useState, useEffect } from "react";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import Axios from "axios";
import Home from "./components/pages/Home";
import LandingPage from "./components/pages/LandingPage";
import { ProtectedRoute } from "./components/auth/ProtectedRoute";
import UserContext from "./context/UserContext";

import "./style.css";

export default function App() {
  const [userData, setUserData] = useState({
    token: undefined,
    user: undefined,
  });

  const checkLoggedIn = async () => {
    let token = localStorage.getItem("auth-token");
    if (token === null) {
      localStorage.setItem("auth-token", "");
      token = "";
    }
    const tokenRes = await Axios.post(
      "http://localhost:5000/users/tokenIsValid",
      null,
      { headers: { "x-auth-token": token } }
    );
    if (tokenRes.data) {
      const userRes = await Axios.get("http://localhost:5000/users/", {
        headers: { "x-auth-token": token },
      });
      setUserData({
        token,
        user: userRes.data,
      });
    }
  };

  useEffect(() => {
    console.log('useEffect called');

    checkLoggedIn();
  }, []);

  return (
    <>
      <BrowserRouter>
      <UserContext.Provider value={{ userData, setUserData }}>
            <Switch>
                <Route exact path="/" component={LandingPage} />
                <ProtectedRoute exact path="/home" component={Home} />
            </Switch>
        </UserContext.Provider>
      </BrowserRouter>
    </>
  );
}

ProtectedRoute.js

import React, { useContext } from "react";
import UserContext from "../../context/UserContext";
import { Route, Redirect } from "react-router-dom";

export const ProtectedRoute = ({
  component: Component,
  ...rest
}) => {
  const { userData } = useContext(UserContext);
  return (
    <Route
      {...rest}
      render={props => {
        console.log("USERDATA " + userData.user)
        console.log("TOKEN " + localStorage.getItem("auth-token"))
        if (userData.user) {
          return <Component {...props} />;
        } else {
          return (
            <Redirect
              to={{
                pathname: "/",
                state: {
                  from: props.location
                }
              }}
            />
          );
        }
      }}
    />
  );
};

编辑 过了一会儿,我发现了问题,这个问题在REACT - Check authentication before render APP

中有解释

【问题讨论】:

    标签: reactjs local-storage react-router-dom use-effect use-context


    【解决方案1】:

    过了一会儿我发现了问题,这个问题在REACT - Check authentication before render APP中解释了

    这是我的解决方案,效果很好。

    App.js

    export default function App() {
      const [userData, setUserData] = useState({
        isLoggedIn: false,
        isLoading: true,
        token: undefined,
        user: undefined
      });
    
      const checkLoggedIn = async () => {
        const tokenRes = await validateToken();
        if (tokenRes.data) {
          const userRes = await getUser();
          let token = localStorage.getItem("auth-token");
          setUserData({
            token,
            user: userRes.data,
            isLoggedIn: true,
            isLoading: false
          });
        }
      };
    
      useEffect(() => {
        console.log('useEffect called');
        checkLoggedIn();
      }, []);
    
      console.log("APPPPPP")
      return (
        <>
          <BrowserRouter>
          <UserContext.Provider value={{ userData, setUserData }}>
                <Switch>
                    <Route exact path="/" component={LandingPage} />
                    <ProtectedRoute exact path="/home" component={Home} />
                </Switch>
            </UserContext.Provider>
          </BrowserRouter>
        </>
      );
    }
    

    ProtectedRoute.js

    import React, {useContext} from "react";
    import { Route, Redirect } from "react-router-dom";
    import UserContext from "../../context/UserContext";
    
    const ProtectedRoute = ({ component: Comp, path, ...rest }) => {
      const { userData } = useContext(UserContext);
      console.log(userData.isLoggedIn);
      return (
        <Route path={path} {...rest} 
        render={props => {  
           return userData.isLoggedIn ? (<Comp {...props} />) : (userData.isLoading ? 'Loading...' : <Redirect to="/" />)
          }}
        />
      );
    };
    
    export default ProtectedRoute;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-11
      • 2020-09-30
      • 2020-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-07
      相关资源
      最近更新 更多