我有一个自定义挂钩来管理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];
}

此自定义挂钩声明为在一个屏幕中对两个或多个组件使用相同的localstorage键.e、 g.

const [state, setState] = useLocalStorage('key', false);

此时,由于使用useLocalStorage的组件希望根据localStorage的状态变化工作,因此我们try 使用useLocalStorage返回的状态作为useEffect的第二个参数.

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关于storage event的说法:

当在another document的上下文中修改了存储区域(localStorage)时,Window接口的storage事件触发.

dispatchEvent是必需的,因为我们还需要监听同一文档中的更改.

Javascript相关问答推荐

我在我的Java代码中遇到了问题,代码的一部分看不到先前定义的对象

扩展类型的联合被解析为基类型

VSCode中出现随机行

如何在DYGRAPS中更改鼠标事件和键盘输入

令牌JWT未过期

有没有一种直接的方法可以深度嵌套在一个JavaScript对象中?

如何为仅有数据可用的点显示X轴标签?

无法检索与Puppeteer的蒸汽游戏的Bundle 包价格

如何组合Multer上传?

JAVASCRIPT SWITCH CASE语句:当表达式为';ALL';

将字符串解释为数字;将其重新编码为另一个基数

带元素数组的Mongo聚合

如果未定义,如何添加全局变量

JS/css:将数字输入的S函数和可调整大小的元素S函数绑定在一起

如何在preLoad()中自定义p5.js默认加载动画?

TS node 找不到依赖的模块

JQuery-无法 Select 使用elementor添加的元素的值

我正在用JS编码一个链表,而我编写的一个Prepreend函数并没有按照我的预期工作

智能合同与Ether.js的集成

素材界面如何让自动完成弹出框不受菜单限制