【问题标题】:watch for prop changes with useEffect使用 useEffect 观察道具变化
【发布时间】:2021-01-19 17:11:29
【问题描述】:

当用户单击应用程序training.js 中的页面时,我正在设置一个本地存储值,然后我希望sidebar.js 读取此值,当设置本地存储项时,它仅输出 @ 中的值987654324@ 一旦用户打开或关闭侧边栏,当 props 发生变化时,它不会被拾取,正如我所期望的 useEffect。

如何让 useEffect 在值发生变化时获取它?

training.js

 {typeof window !== 'undefined' && localStorage.setItem(topic.slug, topic.progress)}    

sidebar.js

const Sidebar = () => {
      const structureAndDetails = typeof window !== 'undefined' ? Number(localStorage.getItem('structure-and-details')) : null
      const hydraulics = typeof window !== 'undefined' ? Number(localStorage.getItem('hydraulics')) : null


  useEffect(() => {

   console.log('hydraulics',hydraulics)
  }, [hydraulics])

【问题讨论】:

  • this codesandbox 对你有帮助吗?
  • localStorage 不是反应式的,不能单独观看(除非您使用某些库)。您还可以使用状态管理生态系统(React Context API、redux、mobx 等)来做到这一点

标签: javascript reactjs


【解决方案1】:

如上所述,localStorage 的更改无法被查看。作为一种解决方法,您可以在 localStorage 更改时调度自定义事件:

training.js:

{typeof window !== 'undefined' && localStorage.setItem(topic.slug, topic.progress)}
document.dispatchEvent(new Event('storageChanged'));

sidebar.js

const Sidebar = () => {
  const storageHandler = useCallback(() => {
    const structureAndDetails = typeof window !== 'undefined' ? Number(localStorage.getItem('structure-and-details')) : null
    const hydraulics = typeof window !== 'undefined' ? Number(localStorage.getItem('hydraulics')) : null
    
    console.log('hydraulics',hydraulics)
  }, []);

  useEffect(() => {
    document.addEventListener("storageChanged", storageHandler, false);

    // Don't forget to remove event listener on component unmount
    return () => {
      document.removeEventListener("storageChanged", storageHandler);
    };
  }, [storageHandler]);

  ...
}

【讨论】:

    【解决方案2】:

    您可以使用 React useEffect 挂钩通过storage events“监听”localStorage 中的更改。

    Window 界面的storage 事件在存储区域时触发 (localStorage) 已在另一个文档的上下文中进行了修改。

    使用useEffect 挂钩添加侦听器、处理程序和清理函数。

    React.useEffect(() => {
      const checkStorage = () => {
        const myValue = window.localStorage.getItem(topic.slug);
    
        // handle updated value
      };
    
      window.addEventListener("storage", checkStorage);
    
      checkStorage();
    
      return () => window.removeEventListener("storage", checkStorage);
    }, []);
    

    一个关键的警告是,正如上面引用中的斜体字和此answer 中所解释的那样,存储事件并未得到普遍支持,并且它可能不适用于在同一窗口中运行的应用程序。

    尝试以下演示,并注意它在同一个窗口中不起作用,但如果您在两个窗口/选项卡中打开沙箱,它会起作用。如果您希望应用程序的不同部分侦听和处理应用程序其他部分对“应用程序状态”的更改,我认为使用 localStorage 不是您想要的。这就是 React Context APIRedux 等解决方案的用途。

    【讨论】:

      猜你喜欢
      • 2020-03-26
      • 1970-01-01
      • 2018-01-15
      • 2020-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-05
      • 2014-02-15
      相关资源
      最近更新 更多