为什么每次刷新页面localStorage都会被清空?

问题描述 投票:0回答:4

就像标题所说,我设置的 localStorage 注册了对

todoList
数组所做的更改,并且
JSON.stringify
是它;但是,每当我刷新页面时,数组都会返回默认的
[]
状态。

const LOCAL_STORAGE_KEY = "task-list"

function TodoList() {
    const [todoList, setTodoList] = useState([]);

    useEffect(() => {
        const storedList = JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY));
        if (storedList) {
            setTodoList(storedList);
        }
    }, []);
    
    useEffect(() => {
        localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(todoList));
    }, [todoList]);
reactjs react-hooks local-storage use-effect use-state
4个回答
16
投票

当您重新加载应用程序/组件时,两个效果都会运行,并且 React 状态更新是异步处理的,因此它会在处理状态更新之前拾取保存到 localStorage 的空数组状态。设置初始

todoList
状态值时直接从localStorage读取即可。

示例:

const LOCAL_STORAGE_KEY = "task-list"

function TodoList() {
  const [todoList, setTodoList] = useState(() => {
    return JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)) || []
  });
    
  useEffect(() => {
    localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(todoList));
  }, [todoList]);

  ...

Edit why-is-localstorage-getting-cleared-whenever-i-refresh-the-page


3
投票

上述解决方案并非在所有情况下都有效。相反,请在

localStorage.setItem
行前面添加一个条件,以防止出现 [] 情况。

//does not work in all cases (such as localhost)
function TodoList() {
  const [todoList, setTodoList] = useState(() => {
    return JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)) || []
  });
//use conditional instead
 useEffect(() => {
    if (todoList.length > 0) {localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(todoList))}
  }, [todoList])

1
投票

您的 React 版本高于 v18,它实现了 。如果在 index.js 中启用此代码

useEffect(() => {
    const storedList = JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY));
    if (storedList) {
        setTodoList(storedList);
    }
}, []);

不起作用,因为它检测到潜在的问题。如果你删除了,它会起作用,但我不会推荐它。最好的解决方案是前两个答案


0
投票

本文演示了如何避免在首次渲染时运行

useEffect
钩子。

这是您修改后的代码,不会在初始渲染时覆盖 localStorage:

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

const LOCAL_STORAGE_KEY = "task-list"
const isMounted = useRef(false);

function TodoList() {
  const [todoList, setTodoList] = useState([]);

  useEffect(() => {
    const storedList = JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY));
    if (storedList) {
        setTodoList(storedList);
    }
  }, []);

  useEffect(() => {
    // don't store on initial render
    if (isMounted.current) {
      localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(todoList));
    } else {
      isMounted.current = true;
    }
  }, [todoList]);
}
© www.soinside.com 2019 - 2024. All rights reserved.