(文档已经过时)react-router README 中文

React Router

文档已经过时! 请查看最新版本 http://rackt.github.io/react-router/

原文: https://github.com/rpflorence/react-router/blob/master/README.md

为 React 定制的完整 routing 模块.

功能

  • 嵌套的 View 映射到嵌套的 Routes
  • route 层级模块化的建构
  • 完全异步的 transition 钩子
  • transition 的 abort / redirect / retry
  • 动态的片段
  • Query 参数
  • 当路由被激活时,自动给 Links 加 .active class
  • 多个顶级 routes
  • Hash 或者 HTML5 历史的 url

查看 examples 目录来了解前面复杂的 UI 和工作流是怎么创建的.

安装

shnpm install react-nested-router
# or
bower install react-router

这个模块是用 Commonjs 模块写的,如果你是用 browserify,Webpack,这之类的,
你可以当作是其他从 npm 安装的模块一样处理.

在 Bower 上还有一个 UMD 构建的版本,通过 window.ReactRouter 引用模块.

用法

var Route = require('react-nested-router').Route;

React.renderComponent((
  <Route handler={App}>
    <Route name="about" handler={About}/>
    <Route name="users" handler={Users}>
      <Route name="user" path="/user/:userId" handler={User}/>
    </Route>
  </Route>
),document.body);

如果 JSX 对你来说不算美味的话:

jsReact.renderComponent((
  Route({handler: App},Route({name: "about",handler: About}),Route({name: "users",handler: Users},Route({name: "user",path: "/user/:userId",handler: User})
    )
  )
),document.body);
  • url 会被映射到最深的 route,随后所有上方层级的 routes 会被激活,
    对应的 handlers(等同 React components)会被渲染.

  • 每个 handler 会接收到一个 params 属性,包含从 url 中匹配到的参数,比如 :userId.

  • handler 还好收到一个 query 属性,是当前的 query 参数的词典.

  • 父级的 routes 会接收到一个 activeRouteHandler 属性,是一个函数,用来渲染激活的子元素.

应用的其余部分是这样的:

jsvar Link = require('react-nested-router').Link;

var App = React.createClass({
  render: function() {
    return (


<div>
        <ul>
          <li><Link to="about">About</Link></li>
          <li><Link to="users">Users</Link></li>
          <li><Link to="user" userId="123">User 123</Link></li>
        </ul>
        <this.props.activeRouteHandler/>
      </div>


    );
  }
});

var About = React.createClass({
  render: function() {
    return 

<h2>About</h2>

;
  }
});

var Users = React.createClass({
  render: function() {
    return (


<div>
        <h2>Users</h2>
        <this.props.activeRouteHandler/>
      </div>


    );
  }
});

var User = React.createClass({
  render: function() {
    return 

<div>{this.props.params.userId}</div>


  }
});

要更好地理解 activeRouteHandler 做了什么,也许一个没有 router 的例子会有用.
比如某个场景 /users/2 被选中,你不用 router 来渲染,看起来像是这样:

jsrender: function() {
  var user = <User params={{userId: 2}}/>;
  var users = <User activeRouteHandler={user}/>;
  return <App activeRouteHandler={users}/>;
}

而 router 可以帮你管理 view 的层级关系.

这个方案的好处

  1. 惊人的创建页面的生产力 - 用户访问 route 只有一个场景: 渲染.
    每个 UI 都有 layer(或者嵌套),可能是简单的导航栏,或者多层的主从结构.
    把嵌套的 routes 和对应嵌套的 View 耦合在一起,减去了很多切换过程中两者纠缠的工作.
    添加新的页面就更快了.

  2. 快速理解应用结构 - 当 routes 是在一个地方写清楚的,开发者很快能从整体看清全局.
    这像是一个基础的 sitemap. 别的办法也没法把应用的那么多信息展示得更快了.

  3. 代码的可操作性 - 当有其他的开发者来修复某个 url 的 bug,他只要做:
    1) 看懂 route 的设置,2) 找到对应 route 的 handler.
    每个应用的入口都会在这些 routes 当中展示出来.

  4. url 是你第一件想的事情,而不是回头想的事情 - 借助 React 嵌套的 router,
    配置 url 以前你是不会得到那么一个页面的. 幸运的是,这个方案开发小略非常高.

相关的模块

API

Route (component)

配置 component,声明应用的 routes 和 View 的层级.

Props(属性)

location - 这个方法用在初始化 router 时页面的导航.

可以是 "hash" 表示在 url 当中使用 hash 并监听 hashchange 事件,
或者 "history" 表示使用 HTML5 History API.
这个属性只能在宣染尽页面的第一层的 route 当中使用.
认值是 "hash".

name - route 的名字,在 Link component 和 router 的 transition 方法当中使用.

path - 在 url 当中使用的 path,支持动态生成的片段.
如果这个属性没有被定义(undefined),这个 path 将会被定义为 name 的值.
这个 path 永远是绝对路径,即便开头的斜线 / 没有加上.
嵌套的 routes 不会从父级继承 path 的内容.

handler - 当 route 匹配时会被渲染的 component.

子元素

routes 是可以嵌套的. 当子级的 route 匹配了,
父级 route 的 handler 会有个子级 route 的 handler 的实例,
可以通过 this.props.activeRouteHandler() 调用.
你可以在父级当中渲染,可以传入任何额外需要的属性.

例子

xml<Route handler={App}>
  <!-- path 被自动赋值到 name 上,因为 name 省略了 -->
  <Route name="about" handler={About}/>
  <Route name="users" handler={Users}>
    <!-- note the dynamic segment in the path -->
    <!-- 注意 path 当中的动态片段 -->
    <Route name="user" handler={User} path="/user/:id"/>
  </Route>
</Route>

或者不用 JSX:

jsRoute({handler: App},Route({name: 'about',Route({name: 'users',Route({name: 'user',handler: User,path: '/user/:id'})
  )
);

Route Handler (用户定义的 component)

传给 route 的 handler 属性的另一个 component,当 route 被激活时会渲染到页面上.
这些 components 上会有一些特殊的属性和一些静态的方法.

Props(属性)

this.props.activeRouteHandler(extraProps) - 活跃的子节点的 route handler.
在渲染方法当中通过这个渲染子级的 route,传入额外需要的参数.

this.props.params - 当 route 中存在形如 <Route path="users/:userId"/> 的动态片段,
这些动态的数据就可以在比如 this.props.params.userId 当中吊桶.

this.props.query - url 的 query 参数.

静态方法 (transition 的钩子)

你可以在 route handlers 上定义静态方法,方法将在 route 的 transition 进行时被调用.

willTransitionTo(transition,params) - 在 route 即将被渲染时调用.
这样你有有机会去中止 transition 过程.
你也可以返回一个 promise,这样整个 route 层级在继续执行前会先等待 promise 被完成.
这一点对服务端渲染非常有用,你会需要在 handler 被渲染前构建一些数据.

willTransitionFrom(transition,component) - 在 route transition 开始时调用,
这样就有机会去中止 transition.
这里的 component 是当前的 component,你可能会需要检查 state 来决定是否运行 transition.

Transition (对象)

transition.abort() - 中止 transition

transition.redirect(to,params,query) - 重定向到另一个 route

transition.retry() - 重试某个 transition

例子

jsvar Settings = React.createClass({
  statics: {
    willTransitionTo: function(transition,params) {
      return auth.isLoggedIn().then(function(loggedIn) {
        if (!loggedIn)
          return;
        transition.abort();
        return auth.logIn({transition: transition});
        // in auth module call `transition.retry()` after being logged in
      });
    },willTransitionFrom: function(transition,component) {
      if (component.formHasUnsavedData())) {
        if (!confirm('You have unsaved information,are you sure you want to leave this page?')) {
          transition.abort();
        }
      }
    }
  }

  //...
});

Link (Component)

创建一个锚点元素,链接到应用的一个 route. 当 route 匹配时自动增加 active class.
如果你改变 route 的 path,不一定要改变你写的 links.

Properties(属性)

to - 链接的到的 route 的名字.

query - 对象,添加到 link 上的 query 参数.
从 route handler 上通过 this.props.query 来访问 query 参数.

[param] - route 定义时传入的任何参数会被传入 link 的属性.

例子

当 route 是 <Route name="user" path="/users/:userId"/>:

xml<Link to="user" userId={user.id} params={{foo: bar}}>{user.name}</Link>
<!-- 根据 route 是否被激活,router 变成其中的一个 -->
<a href="/users/123?foo=bar" class="active">Michael</a>
<a href="#/users/123?foo=bar">Michael</a>

顶层的静态方法

router 有几个顶层的方法可以用来对应用进行导航.

jsvar Router = require('react-nested-router')

transitionTo(routeName,[params[,query]]) - 通过程序 transition 到新的 route.

jsRouter.transitionTo('user',{id: 10},{showAge: true});
Router.transitionTo('about');

replaceWith(routeName,query]]) - 通过程序把当前的 route 替换为新的 route.
但是不在浏览器的历史里增加记录.

jsRouter.replaceWith('user',{showAge: true});
Router.replaceWith('about');

goBack() - 通过程序返回前一个 route 并从浏览器历史记录删去最近的一条记录.

jsRouter.goBack();

开发

查看 CONTRIBUTING

感谢 Ember

这个模块很大程度上收到 Ember.js router API 的启发. 一般来说,这是个 Ember router API 在 React 当中的一个翻译. 深深感谢 Ember 团队他们已经把最难的部分解决了.

相关文章

react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接...
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc ...