反应路由器。为什么在更改路由时,组件会渲染 2 次,从而导致向服务器发出 2 次请求?
React Router. Why, when changing the route, the component is rendered 2 times, which causes 2 requests to the server?
我正在使用 ReactTransitionGroup 和 ReactRouter.
目标是从一个组件平滑地重新路由到另一个组件。 问题 - 组件被渲染两次。
An example of a component (view) that renders twice
我正在使用控制台检查。你可能会说这并不重要。但是,问题是由于这个问题,2 个请求转到服务器(一个额外的)。因此,我希望摆脱这个错误。
This is the component itself - the switch
When switching a route, the console issues logs twice
我需要弄清楚为什么会调用两次副作用。如果没有足够的信息,则写评论。我会尽快回复。
UPD: 我记得很清楚,曾经它像发条一样运转。但是,可能是我自己没有注意到我改变了什么,导致了这个问题。
UPD: 需要代码的话请,需要的元素:
const TabList = ({ tabs }) => {
return (
<nav className="p-my-company__tabs">
{tabs.map(({ to, label, id }) => (
<NavLink to={to} key={id}>
<div>{label}</div>
</NavLink>
))}
</nav>
);
};
const TabViews = ({ tabViews }) => {
const location = useLocation();
return (
<div className="p-my-company__views">
<TransitionGroup>
<SwitchTransition mode="out-in">
<CSSTransition
key={location.pathname}
classNames={{
enter: 'move-enter',
enterActive: 'move-enter-active',
exit: 'move-exit',
}}
timeout={100}>
<Switch>
{tabViews.map(({ path, Component, id }) => (
<Route path={path} render={() => <Component />} key={id} />
))}
</Switch>
</CSSTransition>
</SwitchTransition>
</TransitionGroup>
</div>
);
};
<div className="p-my-company__panel">
<TabList
tabs={[
{ to: ROUTES.COMMON_INFO, label: 'Общая информация', id: 1 },
{ to: ROUTES.SHOWCASE, label: 'Моя витрина', id: 2 },
]}
/>
<TabViews
tabViews={[
{ path: ROUTES.COMMON_INFO, Component: CommonView, id: 1 },
{ path: ROUTES.SHOWCASE, Component: ShowCaseView, id: 2 },
]}
/>
</div>
const ShowCase = () => {
useEffect(() => {
console.log(2);
}, []);
return <div>ShowCase</div>;
};
看起来来自 React Router 和 React Transition Group 的 Switch
组件不能很好地协同工作。 docs 建议避免使用 Switch
组件并将函数传递给 Route
的 children
属性。由于无论是否存在 match
都会调用该函数,因此您可以有条件地呈现 Component
如果有
<>
{tabViews.map(({ path, Component }) => (
<Route exact path={path} key={path}>
{({ match }) => (
<TransitionGroup>
<SwitchTransition mode="out-in">
<CSSTransition
in={match != null}
classNames={{
enter: 'move-enter',
enterActive: 'move-enter-active',
exit: 'move-exit',
}}
timeout={100}
unmountOnExit
key={location.pathname}
>
<div className="page">{match && <Component />}</div>
</CSSTransition>
</SwitchTransition>
</TransitionGroup>
)}
</Route>
))}
</>
我正在使用 ReactTransitionGroup 和 ReactRouter.
目标是从一个组件平滑地重新路由到另一个组件。 问题 - 组件被渲染两次。
An example of a component (view) that renders twice
我正在使用控制台检查。你可能会说这并不重要。但是,问题是由于这个问题,2 个请求转到服务器(一个额外的)。因此,我希望摆脱这个错误。
This is the component itself - the switch
When switching a route, the console issues logs twice
我需要弄清楚为什么会调用两次副作用。如果没有足够的信息,则写评论。我会尽快回复。
UPD: 我记得很清楚,曾经它像发条一样运转。但是,可能是我自己没有注意到我改变了什么,导致了这个问题。
UPD: 需要代码的话请,需要的元素:
const TabList = ({ tabs }) => {
return (
<nav className="p-my-company__tabs">
{tabs.map(({ to, label, id }) => (
<NavLink to={to} key={id}>
<div>{label}</div>
</NavLink>
))}
</nav>
);
};
const TabViews = ({ tabViews }) => {
const location = useLocation();
return (
<div className="p-my-company__views">
<TransitionGroup>
<SwitchTransition mode="out-in">
<CSSTransition
key={location.pathname}
classNames={{
enter: 'move-enter',
enterActive: 'move-enter-active',
exit: 'move-exit',
}}
timeout={100}>
<Switch>
{tabViews.map(({ path, Component, id }) => (
<Route path={path} render={() => <Component />} key={id} />
))}
</Switch>
</CSSTransition>
</SwitchTransition>
</TransitionGroup>
</div>
);
};
<div className="p-my-company__panel">
<TabList
tabs={[
{ to: ROUTES.COMMON_INFO, label: 'Общая информация', id: 1 },
{ to: ROUTES.SHOWCASE, label: 'Моя витрина', id: 2 },
]}
/>
<TabViews
tabViews={[
{ path: ROUTES.COMMON_INFO, Component: CommonView, id: 1 },
{ path: ROUTES.SHOWCASE, Component: ShowCaseView, id: 2 },
]}
/>
</div>
const ShowCase = () => {
useEffect(() => {
console.log(2);
}, []);
return <div>ShowCase</div>;
};
看起来来自 React Router 和 React Transition Group 的 Switch
组件不能很好地协同工作。 docs 建议避免使用 Switch
组件并将函数传递给 Route
的 children
属性。由于无论是否存在 match
都会调用该函数,因此您可以有条件地呈现 Component
如果有
<>
{tabViews.map(({ path, Component }) => (
<Route exact path={path} key={path}>
{({ match }) => (
<TransitionGroup>
<SwitchTransition mode="out-in">
<CSSTransition
in={match != null}
classNames={{
enter: 'move-enter',
enterActive: 'move-enter-active',
exit: 'move-exit',
}}
timeout={100}
unmountOnExit
key={location.pathname}
>
<div className="page">{match && <Component />}</div>
</CSSTransition>
</SwitchTransition>
</TransitionGroup>
)}
</Route>
))}
</>