Невозможно получить доступ к обновленному localStorage в дочернем компоненте (React) - PullRequest
0 голосов
/ 12 июля 2020

В родительском компоненте я получаю данные из API, затем сохраняю их в localStorage. В Parent есть компонент React Router Switch and Route to Child. Сразу после того, как я очищаю свой localStorage и обновляю sh страницу, родительские данные извлекают данные из API и сохраняют их в localstorage, но я не могу получить доступ к localstorage в дочернем элементе.

Parent:

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

1 Ответ

0 голосов
/ 12 июля 2020

Причина вашей проблемы:

Как вы знаете, дочерний элемент является частью цикла рендеринга вашего родителя.

Итак рассмотрим здесь родителя: будучи функциональным компонентом, сначала выполняется возвращенный JSX, затем выполняются хуки useEffect, поскольку компоненты, будь то функциональные или компонент на основе классов, все запускают рендеринг один раз перед переходом к жизненному циклу компонента.

Следовательно, теперь ваш дочерний компонент был отрисован еще до вызова вашего API.

Чтобы отладить это, вы можете создать console.log для вашего используйте эффект в parent , который будет запускать при монтировании. Аналогично и в Child.

Также журналы могут быть добавлены при запуске компонентов поскольку функция запускается при вызове рендеринга.

Это приведет к:

// журнал из дочернего useEffect // журнал из родительского useEffect

Что является точным причина для тебя ou, чтобы не получать данные в дочернем элементе.

Решение вашей проблемы:

Основное решение для вас - задержать ребенка с рендеринг до тех пор, пока не будет выполнен вызов API, который может быть основан на флаге или перечислении или даже на самих данных, которые могут стать частью состояния для родителя.

Я бы рекомендовал вам выбрать указанные выше параметры, а также избегайте использования localstorage, поскольку это не гарантирует возможности использования localStorage. Вы могли бы использовать его как состояние и передать его дочернему элементу в качестве реквизита, или, если ваш вариант использования представляет собой более крупное дерево компонентов, можно рассмотреть контекст или редукцию.

...