首页 > 解决方案 > 父组件无法访问子组件中设置的会话存储值

问题描述

当我尝试在登录后检索token存储的内容时遇到问题。sessionStorage

当我尝试访问sessionStorage时,我可以看到token,但由于某种原因,apiClient无法识别它。注销路由受到保护,因此它需要一个通过标头发送的令牌(请参阅 参考资料api.js)。但是,如果我刷新浏览器,我可以注销这是一个奇怪的活动。

我不确定问题是否与apiClient事物的呈现方式有关或只是如何呈现。

登录代码基于此 GitHub存储库。请在下面查看我的代码。

api.js

import axios from "axios";

const apiClient = axios.create({
  baseURL: "https://some_url",
  withCredentials: true,
  headers: {
    Authorization: `Bearer ${sessionStorage.getItem("token")}`,
  },
});

export default apiClient;

登录表单.js

import React, { useState } from "react";
import { Alert, Button, Form, FormGroup, Input } from "reactstrap";
import { Redirect } from "react-router-dom";
import apiClient from "../../services/api";

const LoginForm = (props) => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [isHome, setIsHome] = useState(false);
  const [authError, setAuthError] = useState(false);
  const [unknownError, setUnknownError] = useState(false);

  const handleSubmit = (e) => {
    e.preventDefault();

    setAuthError(false);
    setUnknownError(false);

    apiClient.get("/sanctum/csrf-cookie").then((_) => {
      apiClient
        .post("/api/v1/login", {
          email: email,
          password: password,
        })
        .then((response) => {
          if (response.status === 201) {
            sessionStorage.setItem("token", response.data.token);
            props.login();
            setIsHome(true);
          }
        })
        .catch((error) => {
          if (error.response.status === 401) {
            setAuthError(true);
          } else {
            setUnknownError(true);
          }
        });
    });
  };

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

  return (
    <>
      <h1 style={{ marginTop: "10px" }}>Login</h1>
      <Form onSubmit={handleSubmit}>
        <FormGroup>
          <Input
            type="email"
            name="email"
            placeholder="Email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            required
          />
        </FormGroup>
        <FormGroup>
          <Input
            type="password"
            name="password"
            placeholder="Password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
          />
        </FormGroup>
        {authError ? (
          <Alert color="danger">
            Cannot recognize your credentials. Please try again.
          </Alert>
        ) : null}
        {unknownError ? (
          <Alert color="danger">
            There was a problem submitting your credentials.
          </Alert>
        ) : null}
        <Button>Submit</Button>
      </Form>
    </>
  );
};

export default LoginForm;

App.js

import React, { useState } from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import {
  Collapse,
  Container,
  Navbar,
  NavbarToggler,
  NavbarBrand,
  Nav,
  NavItem,
  NavLink,
} from "reactstrap";
import LoginForm from "./components/Forms/LoginForm";
import apiClient from "./services/api";

const App = () => {
  const [isOpen, setIsOpen] = useState(false);
  const [isLoggedIn, setIsLoggedIn] = useState(
    sessionStorage.getItem("isLoggedIn") === "true" || false
  );

  const toggle = () => setIsOpen(!isOpen);

  const login = () => {
    setIsLoggedIn(true);
    sessionStorage.setItem("isLoggedIn", true);
  };

  const logout = () => {
    apiClient.post("/api/v1/logout").then((response) => {
      if (response.status === 200) {
        setIsLoggedIn(false);
        sessionStorage.clear();
        alert('You are logged in.')
      }
    });
  };

  const authLink = isLoggedIn ? (
    <NavLink onClick={logout} style={{'cursor': 'pointer'}}>Logout</NavLink>
  ) : (
    <NavLink href="/login">Login</NavLink>
  );

  if (isLoggedIn) alert('You are logged in.')

  return (
    <Router>
    <Navbar color="dark" dark expand="md">
        <NavbarBrand href="/">Student Management System</NavbarBrand>
        <NavbarToggler onClick={toggle} />
        <Collapse isOpen={isOpen} navbar>
        <Nav className="mr-auto" navbar>
            <NavItem>{authLink}</NavItem>
        </Nav>
        </Collapse>
    </Navbar>
    <Container>
        <Switch>
        <Route
            path="/login"
            render={(props) => <LoginForm {...props} login={login} />}
        />
        </Switch>
    </Container>
    </Router>
  );
};

export default App;

标签: reactjslaravelreact-hooks

解决方案


推荐阅读