【问题标题】:Advantages of dynamic vs static routing in ReactReact 中动态与静态路由的优势
【发布时间】:2018-07-26 19:17:43
【问题描述】:

我正在阅读 React Router 中的 static vs dynamic routing,我正在努力确定后者的优势(以及为什么 v4 选择使用它)。我可以看到列出应用程序的所有路由(静态)以及每个路由映射到的组件的优势,允许您跟踪给定特定 URL 将呈现的内容。但我没有看到动态路线有任何明显的优势。

如果有的话,我只能看到缺点,因为没有明确的方法来查看 URL 将映射到什么状态,而不是从根应用程序元素开始并通过路由工作(尽管我可能弄错了)。

动态路由解决什么情况?为什么它比静态路由更可取(可能特别是在 React 应用中)?

【问题讨论】:

  • 您是否检查过以下内容:stackoverflow.com/questions/46096518/…
  • @salman.zare 嘿!是的。我以 pritesh 使用的方式使用“动态路由”。他给出了一个很好的定义,但没有理由更喜欢“静态路由”

标签: reactjs react-router react-router-v4 dynamic-routing


【解决方案1】:

动态路由

来自反应路由器docs

当我们说动态路由时,我们指的是作为您的路由发生的 应用正在呈现,而不是在 a 之外的配置或约定中 正在运行的应用程序。

将路由视为组件

react-router(pre v4)的早期版本曾经有静态路由。这导致 到应用程序中的集中路由,例如:

<Router>
    <Route path='/' component={Main}>
      <IndexRoute component={Home} />
      <Route path='about' component={About} />
      <Route onEnter={verifyUser} path='profile' component={Profile} />
      ...
    </Route>
</Router>

然而,这并不完全是 React 的做事方式。 React 专注于使用基于组件的逻辑进行组合。因此,与其将我们的 Routes 想象成一个静态系统,我们可以将它们想象成组件,这就是 react-router v4 带来的东西,也是它背后的主要理念。

因此,我们可以像使用任何 React 组件一样使用Route。这让我们可以在构建不同组件时添加Route 组件。这样做的一个好处是我们可以将路由逻辑与需要它们的组件解耦。

嵌套路线

About 组件可以处理所有路由并根据 url 有条件地渲染部分 UI(例如 /about/job/about/life 等)。

要注意的另一件事是Route 组件将呈现该组件以匹配路由或null。例如,下面的Route 为路由/aboutnull(或没有)渲染About 组件。

<Route path='about' component={About} />

这也类似于我们在 React 中用于有条件地渲染组件的方式:

route === '/about' ? <About /> : null

现在,如果我们需要在 About 组件内为路由 /about/job/about/life 渲染一些其他组件,我们可以这样做:

const About = ({ match ) => (
    <div>
        ...
        <Route path={`${match.url}/job`} component={Job} />
        <Route path={`${match.url}/life`} component={Life} />
    </div>
)

动态导入和代码拆分

就我个人而言,我还发现这种方法更适合我使用带有代码拆分的动态导入,因为我可以在我的任何组件中添加动态路由。例如,

import Loadable from 'react-loadable';

const Loading = () => (
    <div />
);

const Job = Loadable({
    loader: () => import('./Job'),
    loading: Loading,
});

const Life = Loadable({
    loader: () => import('./Life'),
    loading: Loading,
});

...

render() {
    return (
        ...
        <Route path={`${match.url}/job`} component={Job} />
        <Route path={`${match.url}/life`} component={Life} />
    )
}

响应式路由

动态路由的另一个很好的用例是创建响应式路由,在 react router docs 和推荐阅读中有很好的解释。这是文档中的示例:

const App = () => (
  <AppLayout>
    <Route path="/invoices" component={Invoices}/>
  </AppLayout>
)

const Invoices = () => (
  <Layout>

    {/* always show the nav */}
    <InvoicesNav/>

    <Media query={PRETTY_SMALL}>
      {screenIsSmall => screenIsSmall
        // small screen has no redirect
        ? <Switch>
            <Route exact path="/invoices/dashboard" component={Dashboard}/>
            <Route path="/invoices/:id" component={Invoice}/>
          </Switch>
        // large screen does!
        : <Switch>
            <Route exact path="/invoices/dashboard" component={Dashboard}/>
            <Route path="/invoices/:id" component={Invoice}/>
            <Redirect from="/invoices" to="/invoices/dashboard"/>
          </Switch>
      }
    </Media>
  </Layout>
)

总结docs,您会注意到使用动态路由将Redirect 添加到大屏幕尺寸变得多么简单和声明性。在这种情况下使用静态路由会非常麻烦,并且需要我们将所有路由放在一个地方。动态路由简化了这个问题,因为现在逻辑变得可组合(就像组件一样)。

静态路由

有些问题是动态路由不容易解决的。 static routing 的一个优点是它允许在渲染之前检查和匹配路线。因此它被证明是有用的,尤其是在服务器端。 React 路由器团队也在研究一个名为 react-router-config 的解决方案,引用自:

随着 React Router v4 的引入,不再有 集中路由配置。有一些用例 了解应用程序的所有潜在路线很有价值,例如:

  1. 在渲染下一个屏幕之前在服务器上或生命周期中加载数据
  2. 按名称链接到路线
  3. 静态分析

希望这可以很好地总结动态路由和静态路由以及它们的用例:)

【讨论】:

    【解决方案2】:

    根据 React-Router 文档:

    当我们说 动态路由 时,我们指的是发生在您的 应用程序正在呈现,而不是在 a 之外的配置或约定中 运行应用程序。这意味着几乎所有东西都是 React 中的组件 路由器。

    解释清楚了,所有路由都没有在应用程序开始时初始化,

    React-router v3 或更低版本中,它使用 static Routes 并且所有 Routes 都会在顶层初始化,并且嵌套曾经像

    <Router>
        <Route path='/' component={App}>
          <IndexRoute component={Dashboard} />
          <Route path='users' component={Users}>
              <IndexRoute component={Home}/>
              <Route path="users/:id" component={User}/> 
          </Route>
        </Route>
    </Router>
    

    通过这个 API 设置,react-router 重新实现了 React 的部分(生命周期等),但它与 React 推荐使用的组合逻辑不匹配。

    动态路由具有以下优点,可以预见

    嵌套路由

    动态路由的嵌套路由更像

    const App = () => (
        <BrowserRouter>
            {/* here's a div */}
            <div>
            {/* here's a Route */}
            <Route path="/todos" component={Todos}/>
            </div>
        </BrowserRouter>
    )
    
    // when the url matches `/todos` this component renders
    const Todos  = ({ match }) => (
        // here's a nested div
        <div>
            {/* here's a nested Route,
                match.url helps us make a relative path */}
            <Route
            path={`${match.path}/:id`}
            component={Todo}
            />
        </div>
    )
    

    在上面的例子中,只有当 /todos 匹配到 route-path 时,才会挂载 Todo 组件,然后才定义 Route 路径/todos/:id

    响应式路线

    React-router 文档对此有很好的用例。

    假设用户导航到/invoices。你的应用适应不同的屏幕尺寸,它们有一个狭窄的视口,所以你只向他们显示发票列表和发票链接dashboard。他们可以从那里更深入地导航。

    但在大屏幕上,导航位于左侧,仪表板或特定发票显示在右侧。

    因此/invoices 不是大屏幕的有效路由,我们希望重定向到/invoices/dashboard。这可能会发生,用户从portait to a landscape mode 旋转他/她的手机。这可以使用动态路由轻松完成

    const Invoices = () => (
      <Layout>
    
        {/* always show the nav */}
        <InvoicesNav/>
    
        <Media query={PRETTY_SMALL}>
          {screenIsSmall => screenIsSmall
            // small screen has no redirect
            ? <Switch>
                <Route exact path="/invoices/dashboard" component={Dashboard}/>
                <Route path="/invoices/:id" component={Invoice}/>
              </Switch>
            // large screen does!
            : <Switch>
                <Route exact path="/invoices/dashboard" component={Dashboard}/>
                <Route path="/invoices/:id" component={Invoice}/>
                <Redirect from="/invoices" to="/invoices/dashboard"/>
              </Switch>
          }
        </Media>
      </Layout>
    )
    

    在 React Router 中使用动态路由,考虑 components,而不是静态路由。

    代码拆分

    网络的一个重要功能是我们不必让访问者在使用之前下载整个应用程序。您可以将代码拆分视为增量下载应用程序。 This is made possible with Dynamic Routing.

    它带来的好处是不需要一次下载所有代码,因此它使初始渲染速度更快。

    Here 是一篇很好的文章,可以帮助你为你的应用设置 codeSplitting

    编写可组合的认证路由

    借助动态路由,它还可以更轻松地编写 PrivateRoutes(一种进行身份验证的 HOC),它允许对用户进行身份验证并为他们提供对特定路由的访问权限并以其他方式重定向。我打的这个电话很笼统

    典型的私人路线如下所示

    const PrivateRoute = ({ component: Component, ...rest }) => (
      <Route
        {...rest}
        render={props =>
          fakeAuth.isAuthenticated ? (
            <Component {...props} />
          ) : (
            <Redirect
              to={{
                pathname: "/login",
                state: { from: props.location }
              }}
            />
          )
        }
      />
    );
    

    并且可以作为

    <PrivateRoute path="/protected" component={Protected} />
    

    【讨论】:

      猜你喜欢
      • 2020-11-22
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 2014-10-01
      • 2022-07-11
      • 2010-09-23
      • 1970-01-01
      相关资源
      最近更新 更多