本地存储中的更改未触发事件侦听器
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=()=>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 上找到的另一个示例(对您更有用)
【讨论】:
以上是关于本地存储中的更改未触发事件侦听器的主要内容,如果未能解决你的问题,请参考以下文章