首页 > 解决方案 > 每次刷新页面时 React Context 数据都未定义

问题描述

我正在制作一个简单的 SPA,您需要先登录才能访问其他页面。我可以成功登录并存储登录数据(名字、姓氏等),因为我计划稍后在其他页面中再次使用这些数据。问题是每当我刷新页面时,它总是清空上下文中的状态,这导致我返回登录页面。我指的是我的 SPA 的链接

我需要这样做?如果有人能指出我应该改变/改进的地方,我将不胜感激。谢谢你。

这是我的代码。

App.js

import React, { useState } from "react";
import { BrowserRouter as Router, Link, Route } from "react-router-dom";

import { AuthContext } from "./context/auth";
import PrivateRoute from "./PrivateRoute";

import Login from "./pages/Login";
import Signup from "./pages/Signup";
import Home from "./pages/Home";
import Admin from "./pages/Admin";

function App() {
  const [authTokens, setAuthTokens] = useState();

  const setTokens = (data) => {
    // console.log("DATA ",data);
    localStorage.setItem("tokens", JSON.stringify(data));
    setAuthTokens(data);
  }

  // console.log(authTokens);

  return (
    <AuthContext.Provider value={{ authTokens, setAuthTokens: setTokens }}>
      <Router>
        <div className="app">
          <ul>
            <li><Link to="/">Home Page</Link></li>
            <li><Link to="/admin">Admin Page</Link></li>
          </ul>
          <Route exact path="/login" component={Login} />
          <Route exact path="/signup" component={Signup} />
          <Route exact path="/" component={Home} />
          <PrivateRoute exact path="/admin" component={Admin} />
        </div>
      </Router>
    </AuthContext.Provider>
  );
}

export default App;
Login.js

import React, { useState } from "react";
import axios from "axios";
import { Link, Redirect } from "react-router-dom";

import { useAuth } from "../context/auth";

import { Card, Form, Input, Button, Error } from "../components/AuthForm";

const Login = () => {
  const [isLoggedIn, setLoggedIn] = useState(false);
  const [isError, setIsError] = useState(false);
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const { setAuthTokens } = useAuth();

  const handleLogin = () => {
    axios
      .post("LOGINLINK", {
        email,
        password,
      })
      .then((result) => {
        if (result.status === 200) {
          setAuthTokens(result.data);
          setLoggedIn(true);
        } else {
          setIsError(true);
        }
      })
      .catch((error) => {
        setIsError(true);
      });
  };

  if (isLoggedIn) {
    return <Redirect to="/" />;
  }

  return (
    <Card>
      <Form>
        <Input
          type="email"
          placeholder="Email"
          value={email}
          onChange={(e) => {
            setEmail(e.target.value);
          }}
        />
        <Input
          type="password"
          placeholder="password"
          value={password}
          onChange={(e) => {
            setPassword(e.target.value);
          }}
        />
        <Button onClick={handleLogin}>Login</Button>
      </Form>
      <Link to="/signup">Don't have an account?</Link>
      {isError && (
        <Error>The username or password provided were incorrect!</Error>
      )}
    </Card>
  );
};

export default Login;

Auth.js

import { createContext, useContext } from "react";

export const AuthContext = createContext();

export function useAuth() {
  console.log("CONTEXT", useContext(AuthContext));
  return useContext(AuthContext);
}

标签: reactjslocal-storagereact-context

解决方案


在您的App组件中,您需要在初始化状态时从 localStorage 获取数据,以便它有一些数据可以开始。

const localToken = JSON.parse(localStorage.getItem("tokens"));
const [authTokens, setAuthTokens] = useState(localToken);

如果用户已经通过身份验证,它将在 localStorage 中可用,否则它将为空。


推荐阅读