Обертывание setState в обратном вызове NavLink выдает неправильное предупреждение setState

У меня есть компонент Tabs, в котором есть куча NavLink. Я пытаюсь показать счетчик загрузки на основе свойства NavLinkisPending родительского компонента. Итак, я показываю счетчик, когда в компоненте NavLink of Tabs есть навигация. Я запускаю индикатор показа только из компонента NavLink. Я отключаю счетчик от родителя, используя navigation.

Родительский компонент выглядит примерно так:

import { useNavigation} from "@remix-run/react";

const [isTabNavigating, setIsTabNavigating] = useState(false);
const navigation = useNavigation();

useEffect(() => {
  if (navigation.state === "idle") setIsTabNavigating(false);
  }, [navigation.state]
);

return (
  <>
    <Tabs setIsTabNavigating = {setIsTabNavigating} />
    { isTabNavigating ? <Spinner /> : <Outlet /> }
  </>
);

И компонент вкладок:

<>
  {tabItems.map((tab) => (
    <div>
       <NavLink to = {tab.link}>
       {
         ({ isPending }) => {
           if (isPending) setIsTabNavigating(true);
           return <span>{tab.title}</span>
         }
       }
       </NavLink>
    </div>
  }
</>

Я получаю это предупреждение: Warning: Cannot update a component while rendering a different component (NavLink). To locate the bad setState() call inside NavLink, follow the stack trace as described in https://reactjs.org/link/setstate-in-render

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Код ставит обновление состояния в очередь во время рендеринга компонента как непреднамеренный побочный эффект.

Вы можете абстрагировать реквизит рендеринга дочерних элементов в компонент React, чтобы обновление состояния isTabNavigating можно было правильно поставить в очередь в методе жизненного цикла, например. через крючок useEffect.

Пример:

const TabItem = ({
  isPending,
  isTabNavigating,
  setIsTabNavigating,
  tab
}) => {
  useEffect(() => {
    // If not currently tab navigating and isPending is true,
    // then update to start tab navigating.
    if (!isTabNavigating && isPending) {
      setIsTabNavigating(true);
    }
  }, [isPending, isTabNavigating, setIsTabNavigating]);

  return <span>{tab.title}</span>;
};
tabItems.map((tab) => (
  <div key = {tab.link}>
    <NavLink to = {tab.link}>
      {({ isPending }) => (
        <TabItem
          isPending = {isPending}
          isTabNavigating = {isTabNavigating}
          setIsTabNavigating = {setIsTabNavigating}
          tab = {tab}
        />
      )}
    </NavLink>
  </div>
}

Передайте как состояние isTabNavigating, так и обратный вызов setIsTabNavigating в качестве реквизита, чтобы они были доступны в под-ReactTree.

const [isTabNavigating, setIsTabNavigating] = useState(false);
const navigation = useNavigation();

useEffect(() => {
  if (navigation.state === "idle"){
    setIsTabNavigating(false);
  }
}, [navigation.state]);

return (
  <>
    <Tabs
      isTabNavigating = {isTabNavigating}
      setIsTabNavigating = {setIsTabNavigating}
    />
    {isTabNavigating ? <Spinner /> : <Outlet />}
  </>
);

Другие вопросы по теме