【问题标题】:React JS Not Read and Write to localStorage in useEffect No ErrorsReact JS 在 useEffect 中没有读写到 localStorage 没有错误
【发布时间】:2020-09-19 02:59:24
【问题描述】:

最终目标是存储 JSON 数据。这样,如果将同一个 github 用户发送到 GitHubUser 组件,它应该从本地存储中加载详细信息,而不是重新调用 API,从而防止网络调用。

关于问题的关键点。

  • 从 github 公共 api 进行简单的提取(没有问题,工作正常)
  • 以 github 用户名作为密钥将数据存储到本地存储(无效)
  • 通过提供 github 用户名作为密钥从本地存储中检索数据(无效)
  • 渲染完成后使用 useEffect 显示 json 数据(工作正常)

localStorage 没有任何错误,但没有保存任何内容。我在 Firefox 和 Edge 上都试过了。对于同一个用户,每次登录更改都会发生网络调用,这是不应该的。

此外,此代码来自我正在关注的一本教科书,这是讨论 fetch 和 useEffect 的页面的精确副本。作者继续解释说它应该可以工作,到目前为止这本书是正确的,没有错误。

我已将代码放在沙箱中 - https://codesandbox.io/s/bold-http-8f2cs

还有,具体代码如下。

import React, { useState, useEffect } from "react";

const loadJSON = key =>
  key && JSON.parse(localStorage.getItem(key));
const saveJSON = (key, data) =>
  localStorage.setItem(key, JSON.stringify(data));

function GitHubUser({ login }) {
  const [data, setData] = useState(
    loadJSON(`user:${login}`)
  );

  useEffect(() => {
    if (!data) return;
    if (data.login === login) return;
    const { name, avatar_url, location } = data;
    saveJSON(`user:${login}`, {
      name,
      login,
      avatar_url,
      location
    });
  }, [data]);

  useEffect(() => {
    if (!login) return;
    if (data && data.login === login) return;
    fetch(`https://api.github.com/users/${login}`)
      .then(response => response.json())
      .then(setData)
      .catch(console.error);
  }, [login]);

  if (data)
    return <pre>{JSON.stringify(data, null, 2)}</pre>;

  return null;
}

//Jay-study-nildana
//MoonHighway
export default function App() {
  return <GitHubUser login="Jay-study-nildana" />;
}

注意:我收到了一些与 useEffect 相关的警告,但我已经隔离它们不是问题,但我认为它们不是问题。它简单地告诉我不要使用依赖数组,因为两个 useEffects 只有一个元素。我是故意使用数组的。

更新 1

我注意到的一件事是,在开发人员工具中,成功调用 API 后没有任何内容存储在本地存储中。所以,现在,我在想,储蓄是行不通的。除非我能正常工作并在开发人员工具中查看存储的数据,否则我不知道负载是否正常工作。

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    首先,如果初始状态是一些计算的结果,你可以提供一个函数来代替,它只会在初始渲染时执行:

    // instead of this
    const [data, setData] = useState(
      loadJSON(`user:${login}`)
    );
    
    // you better have this
    const [data, setData] = useState(() => {
      return loadJSON(`user:${login}`);
    });
    

    其次,你可以用这个useEffect实现你所需要的:

    const [data, setData] = useState(() => { return loadJSON(`user:${login}`); });
    
    useEffect(() => {
      if (!data) {
        fetch(`https://api.github.com/users/${login}`)
        .then((response) => response.json())
        .then((val) => {
          saveJSON(`user:${login}`, val); // put data into localStorage
          setData(val); // update React's component state
        })
        .catch(console.error);
      }
    });
    
    if (data) return <pre>{JSON.stringify(data, null, 2)}</pre>;
    
    return <div>no data</div>;
    

    您将在localStorage 中获取您的数据。如果您需要从那里获取它,请不要忘记您需要使用密钥 user:${login}

    【讨论】:

    • 我不想改进 useEffect 的使用。主要是因为本章的其余部分对这两个 useEffects 进行了单独的修改,所以在我目前的学习情况下,它们的完整性是重要且必不可少的。第一部分,我会试一试,看看它是否能解决我的问题。很快就会更新。
    • 我刚刚意识到,在保存工作之前,我无法专注于加载。我已经用一些额外的细节更新了这个问题。我开始认为 localstorage 有一些不在这里的地方。
    • 您在localStorage 中一无所获,因为您从未向其添加任何内容。您的第二个 useEffect 运行并获取数据 - 并且您更新组件的状态 (setData)。你的第一个 useEffect 没有做任何事情,因为这条线:if (data.login=== login) return。 saveJSON 根本不会被调用。
    猜你喜欢
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    • 2012-04-23
    • 1970-01-01
    • 2022-11-13
    相关资源
    最近更新 更多