React,在页面刷新后使用useEffect丢失localStorage中保存的数据

3

这可能是一个新手问题,但我在使用 useEffect() 钩子时遇到了一些麻烦。我有一个记录笔记应用程序,并希望使数据持久化。我使用了两个 useEffect:一个用于当页面首次刷新/加载时,另一个用于当我向我的应用程序添加新笔记时。

我放了一些日志来检查正在发生什么:

const [notes, setNotes] = useState([
  {
  noteId: nanoid(),
  text: 'This is my 1st note!',
  date: '30/07/2022'
  },
  {
    noteId: nanoid(),
    text: 'This is my 2nd note!',
    date: '30/07/2022'
  }
])

// 1st time the app runs
useEffect(() => {
  const savedNotes = JSON.parse(localStorage.getItem('react-notes'))
  console.log('refresh page call:',savedNotes)

  if(savedNotes) {
    setNotes(savedNotes)
  }
}, [])

//every time a new note is added
useEffect(() => {
  localStorage.setItem('react-notes', JSON.stringify(notes));
  console.log('new note call:', notes)
}, [notes])

这种行为有点奇怪,因为当页面刷新时,新数据会出现在日志中,但随后消失,只保留硬编码的数据:

enter image description here

它还进行了比我预期更多的调用。对于这里发生了什么,您有什么想法吗?

1个回答

5

问题

该问题是由下面的 useEffect 以及你初始设置状态的方式导致的:

useEffect(() => {
  localStorage.setItem('react-notes', JSON.stringify(notes));
  console.log('new note call:', notes)
}, [notes])

上述的 useEffect 在每次 notes 改变时都会运行,也会在挂载时运行。在挂载时,状态等于传递给 useState 的初始数组。因此,localStorage 被设置为该数组。

解决方案

一种解决方案是更改如下所示的设置状态的方式,这样如果有东西,就使用 localStorage 中的内容,否则使用您拥有的初始数组:
const [notes, setNotes] = useState(
  !localStorage.getItem("react-notes")
    ? [
        {
          noteId: nanoid(),
          text: "This is my 1st note!",
          date: "30/07/2022",
        },
        {
          noteId: nanoid(),
          text: "This is my 2nd note!",
          date: "30/07/2022",
        },
      ]
    : JSON.parse(localStorage.getItem("react-notes"))
);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接