首页 文章

React中动态与静态路由的优点

提问于
浏览
15

我正在阅读React路由器中的static vs dynamic routing,而且我没有看到动态路由有任何明显的优势 .

如果有的话,我只能看到缺点,因为没有明确的方法来查看URL将映射到哪个状态,而无需从根应用程序元素开始并按照路径进行操作(尽管我可能会弄错) .

动态路由解决了什么情况?为什么它更适合静态路由(可能特别是在React应用程序中)?

2 回答

  • 11

    动态路由

    从反应路由器docs

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

    将路线视为组件

    早期版本的 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专注于使用基于组件的逻辑的组合 . 因此,我们可以将它们想象为静态系统,而不是将它们想象为静态系统,而是将它们视为组件,这就是路由器v4带来的反应以及它背后的主要理念 .

    因此,我们可以使用 Route ,因为我们将使用任何React组件 . 这使我们可以在构建不同组件时添加 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-router-config的解决方案,引用该解决方案:

    随着React Router v4的推出,不再有集中式路由配置 . 在某些用例中,了解所有应用程序的潜在路径非常有用,例如:在呈现下一个屏幕之前在服务器或生命周期中加载数据按名称链接到路径静态分析

    希望这提供了动态路由和静态路由以及它们的用例的良好总结:)

  • 4

    根据React-Router文档:

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

    很清楚,在您的应用程序开始时,所有路由都没有初始化,

    React-router v3 或以下,它使用 static 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建议使用的组合逻辑不匹配 .

    通过动态路线,可以预见到以下优点

    Nested Routes

    具有动态路由的嵌套路由更像

    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 .

    Responsive routes

    React-router docs有一个很好的用例 .

    考虑用户导航到 /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 ,而不是静态路由 .

    Code Splitting

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

    它带来的好处是不需要立即下载所有代码,因此它可以使初始渲染更快 .

    Here 是一篇很好的文章,可以帮助您为您的应用程序设置代码分割

    Writing Composable Authenticated Routes

    使用动态路由,它还可以更容易地编写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} />
    

相关问题