Javascript 使用useEffect观察道具的变化

Javascript 使用useEffect观察道具的变化,javascript,reactjs,Javascript,Reactjs,当用户单击应用程序training.js中的某个页面时,我正在设置本地存储值,然后我希望该值由sidebar.js读取,当设置本地存储项时,用户打开或关闭侧边栏后,它只在控制台.log中输出该值,当道具改变时,它不会像我预期的那样被拾取 如何让useEffect在值发生变化时提取该值 training.js {typeof window !== 'undefined' && localStorage.setItem(topic.slug, topic.progress)}

当用户单击应用程序
training.js
中的某个页面时,我正在设置本地存储值,然后我希望该值由
sidebar.js
读取,当设置本地存储项时,用户打开或关闭侧边栏后,它只在
控制台.log
中输出该值,当道具改变时,它不会像我预期的那样被拾取

如何让useEffect在值发生变化时提取该值

training.js

 {typeof window !== 'undefined' && localStorage.setItem(topic.slug, topic.progress)}    
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])
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]);

  ...
}
侧边栏.js

 {typeof window !== 'undefined' && localStorage.setItem(topic.slug, topic.progress)}    
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])
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]);

  ...
}

如上所述,无法监视本地存储更改。作为一种解决方法,您可以在更改localStorage时调度自定义事件:

training.js:

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

 {typeof window !== 'undefined' && localStorage.setItem(topic.slug, topic.progress)}    
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])
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]);

  ...
}

您可以使用React
useffect
hook通过“监听”本地存储中的更改

当存储区域打开时,窗口界面的
存储
事件将触发 (
localStorage
)已在另一个文档的上下文中修改

使用
useffect
hook添加侦听器、处理程序和清理功能

React.useEffect(() => {
  const checkStorage = () => {
    const myValue = window.localStorage.getItem(topic.slug);

    // handle updated value
  };

  window.addEventListener("storage", checkStorage);

  checkStorage();

  return () => window.removeEventListener("storage", checkStorage);
}, []);
不过,正如上面引用的斜体字和本文所解释的,一个关键的警告是,存储事件并不是普遍支持的,它可能不适用于在同一窗口中运行的应用程序

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


对您有帮助吗?localStorage不是被动的,不能单独查看(除非您使用某些库)。您还可以使用状态管理生态系统(React-Context-API、redux、mobx等)来实现这一点