使用react钩子添加项目后,我正在尝试同步本地存储。
我有以下代码
function App() {
const [currentStorage, SyncWithLocalStorage] = useState(localStorage || {});
window.addEventListener("storage", e => {
SyncWithLocalStorage(localStorage);
});
return (
<div className="App">
<Note onAddNewNote={AddNoteToLocalStorage}></Note>
<div>
{
Object.keys(currentStorage).map(
key => <Postit key={key} input={currentStorage.getItem(key)}></Postit>
)
}
</div>
</div>
);
}
function AddNoteToLocalStorage(note) {
const { id, input } = note;
localStorage.setItem(id, input);
window.dispatchEvent(new Event('storage'));
}
export default App;
我添加了 window.dispatchEvent 行,因为存储事件未在chrome中触发,因此我必须手动执行。
我的想法是一旦执行AddNoteToLocalStorage(note)
方法,它应该检测到本地存储的更改(正在执行),然后更新状态并触发组件的重新渲染为了显示新的添加。现在不起作用。我需要刷新页面以获取新添加的集合。
答案 0 :(得分:1)
进行以下更改,它应该可以工作。
useEffect
并添加eventListener ONCE。卸载后还删除监听器spread
会更改对象引用并导致重新渲染重构代码段
function App() {
const [currentStorage, SyncWithLocalStorage] = useState(localStorage || {});
const eventListenerFun = e => {
console.log("localStorage", { ...localStorage });
SyncWithLocalStorage({ ...localStorage }); //<----spread it which will cause refrence to change
};
useEffect(() => {
window.addEventListener("storage", eventListenerFun);
return () => window.removeEventListener("storage", eventListenerFun);
}, []);
return (
<div className="App">
<button
onClick={() =>
AddNoteToLocalStorage({ id: Date.now(), input: "hello" })
}
>
add note{" "}
</button>
<div>
hi
{currentStorage &&
Object.keys(currentStorage).map(key => (
<div key={key}>{currentStorage[key]}</div>
))}
</div>
</div>
);
}
function AddNoteToLocalStorage(note) {
const { id, input } = note;
localStorage.setItem(id, input);
window.dispatchEvent(new Event("storage"));
}
export default App;