У меня есть компонент 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





Код ставит обновление состояния в очередь во время рендеринга компонента как непреднамеренный побочный эффект.
Вы можете абстрагировать реквизит рендеринга дочерних элементов в компонент 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 />}
</>
);