首页 > 解决方案 > 无法访问子组件中更新的 localStorage (React)

问题描述

在父组件中,我从 API 获取数据,然后将其保存到 localStorage。在 Parent 中有 React Router 的 Switch 和 Route to Child 组件。在我清理我的 localStorage 并刷新页面后,Parent 从 API 获取数据并将其保存到 localstorage,但我无法访问 Child 元素中的 localstorage。

家长:

const getWarriorsData = () => {
    axios
      .get(APIAddress)
      .then(response => response.data)
      .then(({warriors}) => {
        let warriors_numbers = [];
        warriors.forEach((warrior) => {
          let warriorString = JSON.stringify(warrior);
          localStorage.setItem(warrior.number, warriorString);
          warriors_numbers.push(warrior.number);
        });
        localStorage.setItem('warriorsNumbers', JSON.stringify(warriors_numbers));
        localStorage.setItem('expire', Date.now() + 259200000);
      });
  }; 

useEffect( () => {
    if(localStorage.getItem('expire') < Date.now() || localStorage.getItem('expire') === null ){
      getWarriorsData();
    };
  },[]);

return (
    <Router>
      <MenuContext.Provider value={[linksContext, setLinksContext]}>
        <Menu />
        <Switch>
          <Route path="/" exact component={Child} />
        </Switch>
      </MenuContext.Provider>
    </Router>
  );

孩子

console.log({...localStorage}); //empty after cleaning localstorage and page refresh

标签: reactjslocal-storage

解决方案


您的问题的原因:

如您所知,孩子是父母渲染周期的一部分。

所以在这里考虑父级:作为一个功能组件,首先会执行返回的 JSX,然后执行 useEffect 钩子作为组件,无论是功能组件还是基于类的组件,都将在进入组件的生命周期之前运行一次渲染.

因此,现在您的子组件甚至在您的 API 被调用之前就已经被渲染了。

要对此进行调试,您可以做的是在级中为您的使用效果创建一个console.log,它将在挂载时运行。在 Child 中也是如此。

还可以在组件的开头添加日志,并在调用渲染时执行该函数。

这将导致:

// 从子 useEffect 记录 // 从父 useEffect 记录

这是您没有收到孩子数据的确切原因。

您的问题的解决方案:

您的主要解决方案是延迟子渲染,直到进行 API 调用,这可以基于标志或枚举,甚至可以成为父状态的一部分的数据本身。

我建议您选择上述选项并避免使用 localstorage,因为这不能保证使用 localStorage。您可以将其作为状态并将其作为道具传递给子级,或者如果您的用例是更大的组件树,则可以考虑使用上下文或 redux。


推荐阅读