[英]React, update and detect localStorage changes with a custom hook across different components
我有一個自定義掛鈎來管理localStorage
,如下所示:
import { useEffect, useState } from 'react'
export default function useLocalStorage(key, initValue) {
const [state, setState] = useState(() => {
const value = localStorage.getItem(key);
if (value !== null) {
return JSON.parse(value);
}
localStorage.setItem(key, JSON.stringify(initValue));
return initValue;
})
useEffect(() => {
localStorage.setItem(key, state);
}, [key, state])
return [state, setState];
}
此自定義掛鈎被聲明為在一個屏幕中為兩個或多個組件使用相同的本地存儲鍵。 例如。
const [state, setState] = useLocalStorage('key', false);
此時,由於使用useLocalStorage
的組件要根據localStorage
的狀態變化來工作,所以我們嘗試使用useEffect
返回的狀態作為useLocalStorage
的第二個參數。
useEffect(() => {
foobar()
}, [state]);
我希望useEffect
中的foobar()
函數在聲明此useEffect
的所有組件中的“狀態”發生變化時起作用。 但是, foobar()
僅適用於使用相同useEffect
的多個組件中的一個組件。為什么會發生這種情況? 我如何讓它按照我想要的方式工作?
您應該為存儲更改設置一個事件偵聽器,以便獲得更新的值。 請參閱下面的代碼和有關存儲事件的說明:
import { useEffect, useState } from 'react'
export default function useLocalStorage(key, initValue) {
const [state, setState] = useState(() => {
const value = localStorage.getItem(key);
if (value !== null) {
return JSON.parse(value);
}
localStorage.setItem(key, JSON.stringify(initValue));
window.dispatchEvent(new Event("storage"));
return initValue;
});
useEffect(() => {
localStorage.setItem(key, state);
window.dispatchEvent(new Event("storage"));
}, [key, state]);
useEffect(() => {
const listenStorageChange = () => {
setState(() => {
const value = localStorage.getItem(key);
if (value !== null) {
return JSON.parse(value);
}
localStorage.setItem(key, JSON.stringify(initValue));
window.dispatchEvent(new Event("storage"));
return initValue;
});
};
window.addEventListener("storage", listenStorageChange);
return () => window.removeEventListener("storage", listenStorageChange);
}, []);
return [state, setState];
}
您可能想知道為什么要使用這個dispatchEvent
。 好吧,這就是 MDN 關於存儲事件的說法:
當存儲區域 (
localStorage
) 在another document
的上下文中被修改時,會觸發Window
接口的storage
事件。
這個dispatchEvent
是必需的,因為我們也需要監聽同一個文檔中的變化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.