首页 > 解决方案 > 在对 API 进行 fetch 调用后,如何将数据存储到 localStorage 中?

问题描述

我是使用 React 和 JSX 的新手,在将 API 调用中的数据存储到本地存储时遇到问题。我异步调用 fetch 并且我的调用返回用户对象的 JSON(这是针对基于用户的 Web 应用程序)。当我将该 JSON 项目存储到本地存储中(将其转换为字符串之后)并稍后尝试访问该项目时,localStorage.getItem 返回 null 并且我无法检索数据。任何关于我做错了什么的帮助或见解将不胜感激。

登录.js

import React, { Component, useState } from "react";
import {Button, Form, FormGroup, Label, Input} from 'reactstrap';
import {useHistory} from 'react-router-dom';
export const Login = () => {
    const [email_or_username, setName] = useState('');
    const [password, setPassword] = useState('');
    const [is_contributor, setContributor] = useState(false);
    const history = useHistory();
    return (           
        <div> 
            <Form className="login-form">
                <h1>
                <div className="text-right">
                    <Button
                        href="/register"
                        className=" btn-dark text-right">
                        sign up
                    </Button>
                </div>
                <span className="font-weight-bold">Mindify</span>
                </h1>
                <FormGroup>
                    <Label>Username or Email</Label>
                    <h2></h2>
                    <Input 
                        value={email_or_username} 
                        placeholder = "Username or Email" 
                        onChange={e => setName(e.target.value)}/>
                </FormGroup>

                <FormGroup>
                    <label>Password</label>
                    <h2></h2>
                    <Input 
                        value={password} 
                        placeholder = "Password"
                        onChange={e => setPassword(e.target.value)}/>
                </FormGroup>

                <FormGroup>
                    <div className="text-center">
                    <Input 
                        type="checkbox"
                        value={is_contributor}
                        onChange={e => setContributor(e.target.checked)}/>
                        Contributor
                    </div>                    
                </FormGroup>


                <Button onClick={async () =>{
                     const login = {email_or_username, password, is_contributor};
                     const response = await fetch('http://127.0.0.1:5000/api/login', {
                         method: 'POST',
                         headers:{
                            'Content-Type': 'application/json'
                         },
                         body: JSON.stringify(login)
                     })
                     .then(response => {                         
                         if (response.status === 201) {

                            response.json().then(data => { // store user in localStorage as token
                                window.localStorage.setItem("user", JSON.stringify(data.user));
                                console.log(JSON.parse(window.localStorage.getItem("user"))); // prints correctly here
                            })
                            console.log("Successful Login"); 
                            console.log(JSON.parse(window.localStorage.getItem("user"))); // prints null here

                            const ref="/homepage";
                            history.push(ref);
                            //redirect to home page
                         }
                         else if (response.status === 204) {
                            console.log("Invalid Username or Password or Incorrect Permissions");
                            const ref="/";
                            history.push(ref);
                            // reload login page
                         }
                     })
                     .catch(error => console.log(error))

                    }}
                    className="btn-lg btn-dark btn-block">
                    Log in</Button>               
            </Form>
        </div>);  
}

标签: javascriptreactjsapilocal-storagefetch

解决方案


那是因为response.json()是异步的,因此您需要等待response.json()返回才能执行任何后续逻辑。如果任何后续逻辑依赖于response.json(),您应该修改您的语句,以便仅在返回后才处理所需的逻辑。

response.json().then(data => { 
  window.localStorage.setItem("user", JSON.stringify(data.user));                            
  console.log(JSON.parse(window.localStorage.getItem("user"))); 
  const ref="/homepage";
  history.push(ref);
  // carry out other logic below
})

推荐阅读