反应路由器为什么,当改变路由时,组件被渲染了2次,从而导致了2个对服务器的请求?

问题描述

我将 ReactTransitionGroupReactRouter 一起使用。
目标是从一个组件平滑地重新路由到另一个组件。 问题 - 组件被渲染两次

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

我需要弄清楚为什么副作用会被调用两次。如果没有足够的信息,然后写评论。我会尽快回复

Here's an example from the documentation. I have achieved this effect,but the problem has already been described.

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,{ path: ROUTES.SHOWCASE,Component: ShowCaseView,]}
  />
</div>
const ShowCase = () => {
  useEffect(() => {
    console.log(2);
  },[]);

  return <div>ShowCase</div>;
};

解决方法

看起来来自 React Router 和 React Transition Group 的 Switch 组件不能很好地协同工作。 docs 建议避免使用 Switch 组件并将函数传递给 Routechildren 道具。由于无论是否存在 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>
  ))}
</>

Edit react-router-transition-group-x5f9r