首页 > 解决方案 > 反应路由器。为什么在更改路由时,组件渲染了 2 次,导致向服务器发出 2 次请求?

问题描述

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

渲染两次的组件(视图)示例

我正在使用控制台进行检查。你可能会说这并不重要。但是,问题是由于这个问题,有 2 个请求到达服务器(一个额外的)。因此,我希望摆脱这个错误。

这是组件本身 - 开关

切换路由时,控制台发出两次日志

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

这是文档中的一个示例。我已经实现了这个效果,但是问题已经描述过了。

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>;
};

标签: javascriptreactjsreact-routerreact-router-domreact-transition-group

解决方案


看起来SwitchReact Router 和 React Transition Group 的组件不能很好地协同工作。文档建议避免使用组件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>
  ))}
</>

编辑 react-router-transition-group-x5f9r


推荐阅读