美文网首页我爱编程react
React Router 中文文档 1. React Route

React Router 中文文档 1. React Route

作者: 钟志弘 | 来源:发表于2018-06-10 20:30 被阅读184次

    philosophy_React Router 4.0 的哲学

    这篇文档主要解释了核心组件什么时候应该使用 REACT ROUTER,我们称这种解释为动态路由(Dynamic Routing), 它跟我们所熟悉的静态路由有非常大的不同。

    1.1 什么是静态路由

    如果你使用过 Rails, Express, Angular 之类的框架, 你肯定使用过静态路由。在与之类似的框架中,我们需要在应用程序渲染开始之前,也就是在程序的初始化过程中声明路由。 REACT ROUTER PRE-V4 (初期版本)很大程度上也属于静态路由。首先让我们来看一下在express中是如何配置路由的:

    app.get('/', handleIndex)
    app.get('/invoices', handleInvoices)
    app.get('/invoices/:id', handleInvoice)
    app.get('/invoices/:id/edit', handleInvoiceEdit)
    
    app.listen()
    

    我们留意到,在app.listen方法之前,我们必须要声明路由。跟我们之前用过的客户端路由相似. 在 Angular 中,应用开始渲染之前,你需要最将路由声明在最前面并且将他们应用到最顶层的 AppModule中:

    const appRoutes: Routes = [
      { path: 'crisis-center',
        component: CrisisListComponent
      },
      { path: 'hero/:id',
        component: HeroDetailComponent
      },
      { path: 'heroes',
        component: HeroListComponent,
        data: { title: 'Heroes List' }
      },
      { path: '',
        redirectTo: '/heroes',
        pathMatch: 'full'
      },
      { path: '**',
        component: PageNotFoundComponent
      }
    ];
    
    @NgModule({
      imports: [
        RouterModule.forRoot(appRoutes)
      ]
    })
    
    export class AppModule { }
    

    Ember 框架有一个常规的配置文件routes.js ,它的Build可以帮你读取并导入到应用程序里。同上,在你的app渲染之前的必须步骤(不知道原作者想表达什么,记住这有一个常规文件就好了):

    Router.map(function() {
      this.route('about');
      this.route('contact');
      this.route('rentals', function() {
        this.route('show', { path: '/:rental_id' });
      });
    });
    
    export default Router
    

    虽然这些API不尽相同,但是他们都是共享模块的静态路由。react router v4之前也是这么干的。
    如果想要成功学习REACT ROUTER,你需要忘记以上所讲的东西。

    1.2 背景故事

    坦白讲,我们对我们发布的REACT ROUTER 2.x的发展方向非常的气馁. 我们(Micheal和Ryan)觉得被我们这些API所束缚,并且意识导我们正在重构的部分代码(lifecycles(生命周期)...),跟React给我们构建UI的核心组件并不对接。

    当我们离开酒店大堂准备去一个研讨会,讨论应该怎么应对这个问题的时候,我们随口聊天:“如果我们使用在研讨会上宣传的模板来构建我们的路由,会怎么样呢?”

    仅仅开发了一个小时,我们便有了react router4.0的我们想要的路由的核心概念,我们终结了不在react 外面的 API , 取而代之的是我们创造出来的,对未来的react更加兼容的API。我们相信你肯定会喜欢的。

    1.3 动态路由(Dynamic Routing)

    什么是动态路由? 我们觉得动态路由可以在你的app正在渲染的时候启动,而不是在一个配置或者或者一个正在运行的app外部的常规文件中。 也就是说几乎所有事情都可以通过react router中的一个组件来完成。 现在让我们用60s时间浏览一下API ,来看看它们是如何工作的:

    首先,在你的目标文件中引入router,并且在app的头部渲染它:

    // react-native
    import { NativeRouter } from 'react-router-native'
    
    // react-dom (what we'll use here)
    import { BrowserRouter } from 'react-router-dom'
    
    ReactDOM.render((
      <BrowserRouter>
        <App/>
      </BrowserRouter>
    ), el)
    

    下一步,引入link 组件去链接一个新的地址:

    const App = () => (
      <div>
        <nav>
          <Link to="/dashboard">Dashboard</Link>
        </nav>
      </div>
    )
    

    最后,将你想要渲染的UI渲染到Route组件中。如此,当用户访问/dashboard的时候,你的页面就能正常工作了。

    const App = () => (
      <div>
        <nav>
          <Link to="/dashboard">Dashboard</Link>
        </nav>
        <div>
          <Route path="/dashboard" component={Dashboard}/>
        </div>
      </div>
    )
    

    如果你想要传入一些特定的属性,例如:{match, localtion, history},那么Route会渲染一个<Dashboard {...props} /> 其中,props 包含了这些属性。如果用户并没有访问 /dashboard,那么 Route会返回null. 以上就是关于动态路由的很多事情。

    1.4 嵌套路由(Nested Routes)

    很多路由都有一些例如“嵌套路由”的概念。如果你已经使用之前发布的react router v4,那么你肯定已经知道这个玩意儿了!当你从静态路由配置过度到动态、呈现式路由,你该如何嵌套路由呢? 这跟你嵌套一个div一样简单?

    const App = () => (
      <BrowserRouter>
        {/* here's a div */}
        <div>
          {/* here's a Route */}
          <Route path="/tacos" component={Tacos}/>
        </div>
      </BrowserRouter>
    )
    
    // when the url matches `/tacos` this component renders
    const Tacos  = ({ match }) => (
      // here's a nested div
      <div>
        {/* here's a nested Route,
            match.url helps us make a relative path */}
        <Route
          path={match.url + '/carnitas'}
          component={Carnitas}
        />
      </div>
    )
    

    为什么router 组件没有使用嵌套API( •̀ ω •́ )✧? 因为Route 只是一个组件,就跟DIV一样,所以从现在开始构建route简直跟构建div一样简单!

    让我们来谈些棘手的吧。

    1.5 响应式路由

    考虑一个对用户呈现 /invoices。 你的app需要适应不同尺寸的屏幕, 他们有一个狭小的视图,并且你只能给他们一个发票(invoices)的列表和一个链接到invoice dashboard的链接,从而以进一步导航:

    Small Screen
    url: /invoices
    
    +----------------------+
    |                      |
    |      Dashboard       |
    |                      |
    +----------------------+
    |                      |
    |      Invoice 01      |
    |                      |
    +----------------------+
    |                      |
    |      Invoice 02      |
    |                      |
    +----------------------+
    |                      |
    |      Invoice 03      |
    |                      |
    +----------------------+
    |                      |
    |      Invoice 04      |
    |                      |
    +----------------------+
    

    在大屏幕中,我们想要显示主-从视图,此刻我们的导航条在左边,显示面板/制定发票会显示在右边,例如这样:

    Large Screen
    url: /invoices/dashboard
    
    +----------------------+---------------------------+
    |                      |                           |
    |      Dashboard       |                           |
    |                      |   Unpaid:             5   |
    +----------------------+                           |
    |                      |   Balance:   $53,543.00   |
    |      Invoice 01      |                           |
    |                      |   Past Due:           2   |
    +----------------------+                           |
    |                      |                           |
    |      Invoice 02      |                           |
    |                      |   +-------------------+   |
    +----------------------+   |                   |   |
    |                      |   |  +    +     +     |   |
    |      Invoice 03      |   |  | +  |     |     |   |
    |                      |   |  | |  |  +  |  +  |   |
    +----------------------+   |  | |  |  |  |  |  |   |
    |                      |   +--+-+--+--+--+--+--+   |
    |      Invoice 04      |                           |
    |                      |                           |
    +----------------------+---------------------------+
    

    现在暂停一分钟然后想一想如何将 /invoices url适应两个大小的屏幕。这个路由甚至对大屏幕的路由有效?我们应该在视图中的右边放什么东西?

    Large Screen
    url: /invoices
    +----------------------+---------------------------+
    |                      |                           |
    |      Dashboard       |                           |
    |                      |                           |
    +----------------------+                           |
    |                      |                           |
    |      Invoice 01      |                           |
    |                      |                           |
    +----------------------+                           |
    |                      |                           |
    |      Invoice 02      |             ???           |
    |                      |                           |
    +----------------------+                           |
    |                      |                           |
    |      Invoice 03      |                           |
    |                      |                           |
    +----------------------+                           |
    |                      |                           |
    |      Invoice 04      |                           |
    |                      |                           |
    +----------------------+---------------------------+
    

    在大视图中,/invoices 并不是一个有效的路由(/invoices/dashboard才是),但是在小屏幕中它确是!想让这件事变得更有趣点?加入有人有一个巨大的手机,他们可以在纵向看到 /invoices ,并且如果他们旋转他们的手机到横向。这时我们有足够的空间去显示主-从UI,这时你需要重新定位路由。

    REACT ROUTER 之前版本的静态路由对于这个问题没有确切的答案。然而当路由为动态的时候,你可以编写这个功能。如果你开始把路由想象成UI,而不是静态配置, 你的直觉会让你写出以下代码:

    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>
    )
    

    当用户把他们的手机从横向旋转为纵向的时候, 这段代码会自动重定位到 /invoices/dashboard url中。 路由的改变随着用户手中的设备旋转而改变。

    这仅仅只是单单的案例。还有更多的案例我们可以讨论,但是为了节省时间,我们将这些案例总结为一个忠告:将你的直觉与react router的 保持一致,以组件的形式去实现路由,而不是静态配置形式。思考使用React的声明式组件的思想去解决问题,因为几乎所有react router的问题,都是 react 的问题。

    相关文章

      网友评论

        本文标题:React Router 中文文档 1. React Route

        本文链接:https://www.haomeiwen.com/subject/lshqeftx.html