【问题标题】:How to structure code for a component that changes content on route change, but should not unmount如何为在路由更改时更改内容但不应卸载的组件构建代码
【发布时间】:2021-12-07 05:30:45
【问题描述】:

假设我有以下结构:

  <Router>
    <Sidebar />
    <Switch>
      <Route path='/' exact component={Home} />
      <Route path='/reports' component={Reports} />
      <Route path='/products' component={Products} />
    </Switch>
  </Router>

侧边栏显示在左侧,其余显示在右侧。侧边栏允许从一个页面跳转到另一个页面。此外,我希望每个页面(主页、报告、产品)都有一个顶部菜单,可以根据我所在的页面更改其内容。但是当我使用侧边栏更改页面时,它不应该消失(几分之一秒)。它总是会有相同的样式,只有文本/内容可能会改变。

实现它的最佳方式是什么?如果我将菜单分别放在每个页面中,我认为它会在我更改页面时消失一会儿(因为它需要卸载一个实例并安装另一个实例)。另一方面,如果我将它完全放在 3 条路径之外,即侧边栏旁边,那么将菜单和页面逻辑(方法、道具等)保留在 2 个不同的组件中会很麻烦——毕竟它们是,从概念上讲,是同一个视图的一部分,如果把逻辑放在同一个组件中就好了。

【问题讨论】:

  • 你必须创建带有标题、侧边栏的布局
  • 您可以对您的 Web 应用程序进行布局,并使用 redux 根据您所在的页面更改顶部菜单中的值。

标签: reactjs react-router


【解决方案1】:

如果一组路由共享相同的布局,您可以考虑为这些路由创建单独的路由组件。

const MenuLayout = () => {
  return (
    <React.Fragment>
      <Menu />
      <Switch>
        <Route path='/' exact component={Home} />
        <Route path='/reports' component={Reports} />
        <Route path='/products' component={Products} />
      </Switch>
    </React.Fragment>
  );
}

如果您需要将&lt;Menu /&gt;组件与这些路由连接,您也可以使用Route render prop从路由器组件中注入props。

<Route path="/" render={props => <Home {...props} customProps={true} />} exact />

我也一直在使用自定义 Route 组件,它接受 layout 属性。这个layout 属性是一个包含 NavBar 和 Footer 的组件。使用这种方法,路由保留在一个文件中。

import { Route as ReactRouterRoute, Switch, Redirect } from 'react-router-dom';

const CleanLayout = ({ children }) => (
  <React.Fragment>
    {children}
  </React.Fragment>
);

const MenuLayout = ({ children }) => (
  <React.Fragment>
    <Menu />
    {children}
  </React.Fragment>
);

const Route = ({ component: Component, layout, ...rest }) => {
  const Layout = layout || CleanLayout;

  return (
    <ReactRouterRoute
      {...rest}
      render={props => (
        <Layout>
          <Component {...props} />
        </Layout>
      )}
    />
  );
};

const MenuLayout = () => {
  return (
    <React.Fragment>
      <Menu />
      <Switch>
        <Route path='/' exact component={Home} layout={MenuLayout} />
        <Route path='/reports' component={Reports} layout={MenuLayout} />
        <Route path='/products' component={Products} layout={MenuLayout} />
        <Route path='/onboard' component={Onboard} layout={CleanLayout} />
      </Switch>
    </React.Fragment>
  );
}

【讨论】:

  • 但是当用户从 /reports 切换到 /products 时,不是菜单的一个实例卸载而另一个安装了吗?那样的话,岂不是一瞬间就消失了?
  • 不,因为布局组件没有改变,React 重用了same component
猜你喜欢
  • 2016-01-02
  • 1970-01-01
  • 2019-06-14
  • 2021-05-01
  • 2017-08-19
  • 1970-01-01
  • 2023-01-10
  • 1970-01-01
  • 2017-03-06
相关资源
最近更新 更多