【问题标题】:How to make useEffect listening to any change in localStorage?如何让 useEffect 监听 localStorage 的任何变化?
【发布时间】:2021-08-13 10:34:09
【问题描述】:

我试图让我的 React 应用程序从 localStorage 中获取 todos 对象数组并将其提供给 setTodos。为此,我需要有一个 useEffect 来监听本地存储中发生的任何更改,所以这就是我所做的:

  useEffect(() => {
      if(localStorage.getItem('todos')) {
        const todos = JSON.parse(localStorage.getItem('todos'))
        setTodos(todos);
      }
  }, [ window.addEventListener('storage', () => {})]);

问题是每次我从 localStorage 添加或删除某些内容时都不会触发 useEffect。 这是让 useEffect 监听 localStorage 的错误方式吗?

我尝试了explained here 的解决方案,但它对我不起作用,我真的不明白为什么它应该起作用,因为侦听器没有作为 useEffect 中的第二个参数传递

【问题讨论】:

  • 您是否只想从 localStorage 初始化状态,将状态更新持久化到 localStorage?或者您实际上是否需要监视本地存储以了解其他地方所做的更改?
  • 我很好奇你为什么需要这个?据我所知,localStorage 并非旨在用作应用程序的状态(您只能在其中存储字符串)。还有其他方法可以做到这一点(react 的上下文 API,react-redux)。当然,如果你想让一些数据持久化,你可以将你的 context / redux 与你的 localStorage 同步,但在大多数用例中你不需要它。另外,请记住,localStorage 具有最大容量(每个浏览器每个应用程序 5 MB)。

标签: javascript reactjs


【解决方案1】:

您不能以这种方式重新运行 useEffect 回调,但您可以设置一个事件处理程序并让它重新加载 todos,请参阅 cmets:

useEffect(() => {
    // Load the todos on mount
    const todosString = localStorage.getItem("todos");
    if (todosString) {
        const todos = JSON.parse(todosString);
        setTodos(todos);
    }
    // Respond to the `storage` event
    function storageEventHandler(event) {
        if (event.key === "todos") {
            const todos = JSON.parse(event.newValue);
            setTodos(todos);
        }
    }
    // Hook up the event handler
    window.addEventListener("storage", storageEventHandler);
    return () => {
        // Remove the handler when the component unmounts
        window.removeEventListener("storage", storageEventHandler);
    };
}, []);

请注意,storage event 仅在存储被 不同 窗口中的代码更改为当前窗口时才会出现。如果您在同一窗口中更改todos,则必须手动触发。

【讨论】:

  • 我现在明白了,谢谢。这就是为什么它不起作用
猜你喜欢
  • 2020-07-25
  • 2019-11-01
  • 2021-09-21
  • 2021-06-16
  • 2021-04-15
  • 1970-01-01
  • 2013-04-18
  • 1970-01-01
  • 2018-06-10
相关资源
最近更新 更多