reactjs 使用localStorage值作为useEffect依赖项

sbdsn5lh  于 2023-03-29  发布在  React
关注(0)|答案(2)|浏览(156)

如何在依赖数组中使用benchmarkActiveTab的localstorage值?该值在localstorage中更改,但当该值更改时,useEffect未运行

const [activeTab, setActiveTab] = useState(
  localStorage.getItem("benchmarkActiveTab") || 0
)

useEffect(() => {
  async function getBenchmarkTimes() {
    // this function doesn't run
  }
  getBenchmarkTimes()
}, [activeTab])

我尝试在localStorage.getItem('benchmarkActiveTab')更改时运行useEffect,但useEffect不运行。

fd3cxomn

fd3cxomn1#

您需要侦听storage事件

const [activeTab, setActiveTab] = useState(
  localStorage.getItem("benchmarkActiveTab") || 0
)

useEffect(() => {
  const OnStorageEvent = async () => {
    const value = localStorage.getItem('benchmarkActiveTab') || 0

    if (activeTab !== value) {
      // value change
      setActiveTab(value)

      // Run getBenchmarkTimes here
      // use value instead of activeTab here because react update after re render
    }
  }

  addEventListener("storage", OnStorageEvent)

  return () => removeEventListener("storage", OnStorageEvent)
}, [activeTab])
wfveoks0

wfveoks02#

在你的代码中,状态activeTab在初始渲染时只设置了一次。它不会再改变。所以效果取决于它也不会再运行。
你可以使用useSyncExternalStore钩子。这个钩子接受两种参数:subscribegetSnapshot。每次subscribe调用回调,React都会调用getSnapshot并获取一个新的快照。如果快照发生变化(当Object.is的结果为false时),React会重新渲染组件。

function useLocalStorageValue(key, interval = 100) {
  // run callback intervally
  const subscribe = (callback) => {
    let enabled = true;
    const fn = () =>
      setTimeout(() => {
        callback();
        if (enabled) fn();
      }, interval);
    fn();
    return () => {
      enabled = false;
    };
  };

  // get value from localstorage
  const getSnapShot = () => {
    return localStorage.getItem(key);
  };

  return useSyncExternalStore(subscribe, getSnapShot, getSnapShot);
}

参见完整示例here

相关问题