本地存储中的更改未触发事件侦听器

Posted

技术标签:

【中文标题】本地存储中的更改未触发事件侦听器【英文标题】:Change in localstorage not triggering event listener 【发布时间】:2020-07-14 22:11:44 【问题描述】:

我有 React 组件。最初我在 UseEffect 中设置了一些 localStorage。此外,我添加了事件侦听器。单击文本后,它会更改 localStorage 值,但事件侦听器没有触发,为什么?

import React,  useEffect  from "react";

export default function App() 

  useEffect(() => 
    window.localStorage.setItem("item 1", 'val 1');
    window.addEventListener('storage', () => 
      alert('localstorage changed!')
    )
  , []);

  const getData = () => 
    localStorage.setItem("item", "val chamged");
  ;

  return (
    <div className="App">
      <h1 onClick=getData>Change localstorage value</h1>

    </div>
  );

https://codesandbox.io/s/naughty-engelbart-90tkw

【问题讨论】:

请更新您的代码框,使其与您在此处粘贴的代码相同。您的链接沙箱中没有事件侦听器。 如果您更改沙箱代码以匹配您在此处拥有的代码,特别是 onClick=getData 部分,您将看到它有效。在调用 getData() 函数并传递结果而不是传递函数本身时存在拼写错误。 已更新,但仍无法正常工作 useEffect() 无法检测到更改。我尝试了一些随机哈希来触发 useEffect codesandbox.io/s/serene-hawking-hz6pq 但仍然不知道为什么监听器什么都不做 【参考方案1】:

有两件事不对。

    更改onClick=getData() onClick=getData 来自文档 (https://developer.mozilla.org/en-US/docs/Web/API/Window/storage_event)。 The storage event of the Window interface fires when a storage area (localStorage or sessionStorage) has been modified in the context of another document. 请注意最后一句话,它不会在同一个文档中被解雇。您可以看到,如果您在同一浏览器中的 2 个标签页中打开 https://codesandbox.io/s/spring-browser-89con,就会开始出现警报。

【讨论】:

谢谢,当在同一个文档中进行更改时,您知道如何修复它以使其正常工作吗? 同一文档中不需要。您不能在更新 localStorage 后手动调用处理程序函数。 ?可能会编写一个包装函数来设置本地存储并调用您的回调。【参考方案2】:

当窗口的存储区域发生变化时触发Storage事件。

注意:存储事件仅在窗口时触发 自己进行更改。

您可以查看更多详细信息和演示:storage Event

storage 事件处理程序只会影响其他窗口。每当localStorage 内的一个窗口发生变化时,所有其他窗口都会收到通知,如果需要采取任何措施,可以通过监听storage 事件的处理函数来实现。

【讨论】:

【参考方案3】:

试试这个 onclick 处理程序

import React,  useEffect  from "react";

export default function App() 

  useEffect(() => 
    window.localStorage.setItem("item 1", 'val 1');
    window.addEventListener('storage', () => 
      alert('localstorage changed!')
    )
  , []);

  const getData = () => 
    localStorage.setItem("item", "val chamged");
  ;

  return (
    <div className="App">
      <h1 onClick=()=>getData()>Change localstorage value</h1>

    </div>
  );

【讨论】:

onClick=()=&gt;getData()onClick=getData 相同 小斌,如果不需要,最好不要创建多余的匿名函数。【参考方案4】:

我会提出一个解决方案。这可能是一个丑陋的解决方案,但它是我发现从同一个窗口实现它的唯一解决方案。 (由于某些原因,我需要更改 :))

我使用了 MutationObserver 类,例如获取暗模式值的任何更改:

const setTheme = (value) => 
    let htmlClasses = document.querySelector('html').classList
    if (value == true) 
        htmlClasses.add('dark');
     else 
        htmlClasses.remove('dark');
    
    window.localStorage.setItem('dark', value)

这里我在每次激活切换按钮时添加一个类,然后我在 html 类上配置一个观察者,如下所示:

var observer = new MutationObserver(function (mutations) 
  mutations.forEach(function (mutation) 
      console.log(mutation);
      if (mutation.attributeName == "class") 
         // Do what you want here
      
  );
);
var config = 
  attributes: true
;

observer.observe(document.querySelector('html'), config);

您还可以查看我在 github here 上找到的另一个示例(对您更有用)

【讨论】:

以上是关于本地存储中的更改未触发事件侦听器的主要内容,如果未能解决你的问题,请参考以下文章

javascript [JS]事件监听器和设置本地存储

本地存储 index.js 科尔多瓦

ExtJS 更改事件侦听器未能触发

手指信息,本地存储

安全的本地存储 Angular 6

如何区分本地未提交的更改和来源