在代码中遇到了需要在react中监听localStorage的数据,下意识想到的是按照useEffect监听useState变化那一套,但是未生效。
代码如下:
useEffect(()=>{
console.log("变化了")
},[localStorage.getItem('data')])
需要使用监听器
useEffect(() => {
function checkData() {
const item = localStorage.getItem('data')
if (item) {
setData(item)
}
}
window.addEventListener('storage', checkData)
return () => {
window.removeEventListener('storage', checkData)
}
}, [])
但是上述方式有弊端,只能监听同源的两个页面之间的 storage 变更,没法监听同一个页面的变更。
需要自定义事件
const originalSetItem = localStorage.setItem
localStorage.setItem = function (key, newValue) {
const setItemEvent = new Event("setItemEvent")
setItemEvent[key] = newValue
window.dispatchEvent(setItemEvent)
originalSetItem.apply(this, [key, newValue])
}
// 添加事件监听器
function handleSetItemEvent(event) {
console.log("监听到本地存储发生变化了:", event)
console.log("Key:", Object.keys(event)[0])
console.log("Value:", event[Object.keys(event)[0]])
}
window.addEventListener("setItemEvent", handleSetItemEvent)
// 当不再需要时,移除事件监听器
window.removeEventListener("setItemEvent", handleSetItemEvent)
useEffect(() => {
// 重写localStorage.setItem方法,监听本地存储的变化
const originalSetItem = localStorage.setItem
localStorage.setItem = function (key, newValue) {
const setItemEvent = new CustomEvent("setItemEvent", {
detail: { key, newValue },
})
window.dispatchEvent(setItemEvent)
originalSetItem.apply(this, [key, newValue])
}
const handleSetItemEvent = (event) => {
const customEvent = event
if (customEvent.detail.key === "trace_info") {
const updatedTraceInfo = safeParse(customEvent.detail.newValue)
console.log("监听到本地存储发生变化了:", updatedTraceInfo)
处理逻辑...
}
}
window.addEventListener("setItemEvent", handleSetItemEvent)
// 清除事件监听器
return () => {
window.removeEventListener("setItemEvent", handleSetItemEvent)
localStorage.setItem = originalSetItem // 还原本地存储原生方法
}
}, [])
封装为可复用Hook,其中localStorageKey:本地存储的key,callback:监听到本地存储变化后的处理函数
import { useEffect } from "react"
function safeParse(jsonString) {
if (jsonString === null) {
return null
}
try {
return JSON.parse(jsonString)
} catch (error) {
console.error("Error parsing JSON:", error)
return null
}
}
function useLocalStorageListener(localStorageKey, callback) {
useEffect(() => {
const originalSetItem = localStorage.setItem
localStorage.setItem = function (key, newValue) {
const setItemEvent = new CustomEvent("setItemEvent", {
detail: { key, newValue },
})
window.dispatchEvent(setItemEvent)
originalSetItem.apply(this, [key, newValue])
}
const handleSetItemEvent = (event) => {
const customEvent = event
if (event.detail.key === localStorageKey) {
// 这里的key就是本地存储对应的key
const updatedValue = safeParse(customEvent.detail.newValue)
callback(updatedValue) // 将本地存储最新的值传给回调函数
}
}
window.addEventListener("setItemEvent", handleSetItemEvent)
return () => {
window.removeEventListener("setItemEvent", handleSetItemEvent)
localStorage.setItem = originalSetItem
}
}, [localStorageKey, callback])
}
export default useLocalStorageListener
使用该Hook,这里假设监听LocalStorage中key为「data」的数据,并在其变化时执行log。
useLocalStorageListener("data", (updatedTraceInfo) => {
console.log("data最新值:",updatedTraceInfo)
})
1847

被折叠的 条评论
为什么被折叠?



