• API 接口
    • 组件
      • Router
        • Props
          • children (required)
          • routes
          • history
          • createElement(Component, props)
          • stringifyQuery(queryObject)
          • parseQueryString(queryString)
          • onError(error)
          • onUpdate()
        • 示例
      • Link
        • Props
          • to
          • query
          • hash
          • state
          • activeClassName
          • activeStyle
          • onClick(e)
          • 其他
        • 示例
      • IndexLink
      • RoutingContext
    • 组件的配置
    • Route
      • Props
        • path
        • component
        • components
        • getComponent(location, callback)
          • callback signature
        • getComponents(location, callback)
          • callback signature
        • children
        • onEnter(nextState, replaceState, callback?)
        • onLeave()
  • PlainRoute
    • Props
      • childRoutes
      • getChildRoutes(location, callback)
        • callback signature
      • indexRoute
      • getIndexRoute(location, callback)
        • callback signature
  • Redirect
    • Props
      • from
      • to
      • query
  • IndexRoute
    • Props
  • IndexRedirect
    • Props
  • Route Components
    • history
    • location
    • params
    • route
    • routeParams
    • children
      • 示例
  • 已命名的组件
    • 示例
  • Mixins
  • 生命周期 Mixin
    • 生命周期方法
      • routerWillLeave(nextLocation)
      • arguments
  • History Mixin
    • Methods
      • pushState(state, pathname, query)
        • arguments
      • replaceState(state, pathname, query)
        • 参数
      • go(n)
      • goBack()
      • goForward()
      • createPath(pathname, query)
      • createHref(pathname, query)
      • isActive(pathname, query, indexOnly)
        • 参数
    • 示例
    • 但我仍然在使用 Classes
  • RouteContext Mixin
  • Utilities
  • useRoutes(createHistory)
  • match(location, cb)
  • createRoutes(routes)
    • params
      • routes
  • PropTypes

    API 接口

    TODO: Need proofread https://github.com/rackt/react-router/blob/master/docs/API.md

    • 组件

      • Router
      • Link
      • IndexLink
      • RoutingContext
    • 组件的配置

      • Route
      • PlainRoute
      • Redirect
      • IndexRoute
      • IndexRedirect
    • Route 组件

      • 已命名的组件
    • Mixins

      • 生命周期
      • History
      • RouteContext
    • Utilities

      • useRoutes
      • match
      • createRoutes
      • PropTypes

    组件

    Router

    React Router 的重要组件。它能保持 UI 和 URL 的同步。

    Props

    children (required)

    一个或多个的 RoutePlainRoute。当 history 改变时, <Router> 会匹配出 Route 的一个分支,并且渲染这个分支中配置的组件,渲染时保持父 route 组件嵌套子 route 组件。

    routes

    children 的别名。

    history

    Router 监听的 history 对象,由 history 包提供。

    createElement(Component, props)

    当 route 准备渲染 route 组件的一个分支时,就会用这个函数来创建 element。当你使用某种形式的数据进行抽象时,你可以想要获取创建 element 的控制权,例如在这里设置组件监听 store 的变化,或者使用 props 为每个组件传入一些应用模块。

    1. <Router createElement={createElement} />
    2. // 默认行为
    3. function createElement(Component, props) {
    4. // 确保传入了所有的 props!
    5. return <Component {...props}/>
    6. }
    7. // 你可能会使用什么,如 Relay
    8. function createElement(Component, props) {
    9. // 确保传入了所有的 props!
    10. return <RelayContainer Component={Component} routerProps={props}/>
    11. }
    stringifyQuery(queryObject)

    一个用于把 Link 或调用 transitionTo 函数的对象转化成 URL query 字符串的函数。

    parseQueryString(queryString)

    一个用于把 query 字符串转化成对象,并传递给 route 组件 props 的函数。

    onError(error)

    当路由匹配到时,也有可能会抛出错误,此时你就可以捕获和处理这些错误。通常,它们会来自那些异步的特性,如 route.getComponentsroute.getIndexRoute,和 route.getChildRoutes

    onUpdate()

    当 URL 改变时,需要更新路由的 state 时会被调用。

    示例

    请看仓库中的示例目录 examples/,这些例子都广泛使用了 Router

    允许用户浏览应用的主要方式。<Link> 以适当的 href 去渲染一个可访问的锚标签。

    <Link> 可以知道哪个 route 的链接是激活状态的,并可以自动为该链接添加 activeClassNameactiveStyle

    Props

    to

    跳转链接的路径,如 /users/123

    query

    已经转化成字符串的键值对的对象。

    hash

    URL 的 hash 值,如 #a-hash

    注意:React Router 目前还不能管理滚动条的位置,并且不会自动滚动到 hash 对应的元素上。如果需要管理滚动条位置,可以使用 scroll-behavior 这个库。

    state

    保存在 location 中的 state。

    activeClassName

    当某个 route 是激活状态时,<Link> 可以接收传入的 className。失活状态下是默认的 class。

    activeStyle

    当某个 route 是激活状态时,可以将样式添加到链接元素上。

    onClick(e)

    自定义点击事件的处理方法。如处理 <a> 标签一样 - 调用 e.preventDefault() 来防止过度的点击,同时 e.stopPropagation() 可以阻止冒泡的事件。

    其他

    你也可以在 <a> 标签上传入一些你想要的 props,如 titleidclassName 等等。

    示例

    <Route path="/users/:userId" /> 这样的 route:

    1. <Link to={`/users/${user.id}`} activeClassName="active">{user.name}</Link>
    2. // 变成它们其中一个依赖在 History 上,当这个 route 是
    3. // 激活状态的
    4. <a href="/users/123" class="active">Michael</a>
    5. <a href="#/users/123">Michael</a>
    6. // 修改 activeClassName
    7. <Link to={`/users/${user.id}`} activeClassName="current">{user.name}</Link>
    8. // 当链接激活时,修改它的样式
    9. <Link to="/users" style={{color: 'white'}} activeStyle={{color: 'red'}}>Users</Link>

    敬请期待!

    RoutingContext

    在 context 中给定路由的 state、设置 history 对象和当前的 location,<RoutingContext> 就会去渲染组件树。

    组件的配置

    Route

    Route 是用于声明路由映射到应用程序的组件层。

    Props

    path

    URL 中的路径。

    它会组合父 route 的路径,除非它是从 / 开始的,
    将它变成一个绝对路径。

    注意:在动态路由中,绝对路径可能不适用于 route 配置中。

    如果它是 undefined,路由会去匹配子 route。

    component

    当匹配到 URL 时,单个的组件会被渲染。它可以
    被父 route 组件的 this.props.children 渲染。

    1. const routes = (
    2. <Route component={App}>
    3. <Route path="groups" component={Groups}/>
    4. <Route path="users" component={Users}/>
    5. </Route>
    6. )
    7. class App extends React.Component {
    8. render () {
    9. return (
    10. <div>
    11. {/* 这会是 <Users> 或 <Groups> */}
    12. {this.props.children}
    13. </div>
    14. )
    15. }
    16. }
    components

    Route 可以定义一个或多个已命名的组件,当路径匹配到 URL 时,
    它们作为 name:component 对的一个对象去渲染。它们可以被
    父 route 组件的 this.props[name] 渲染。

    1. // 想想路由外部的 context — 如果你可拔插
    2. // `render` 的部分,你可能需要这么做:
    3. // <App main={<Users />} sidebar={<UsersSidebar />} />
    4. const routes = (
    5. <Route component={App}>
    6. <Route path="groups" components={{main: Groups, sidebar: GroupsSidebar}}/>
    7. <Route path="users" components={{main: Users, sidebar: UsersSidebar}}>
    8. <Route path="users/:userId" component={Profile}/>
    9. </Route>
    10. </Route>
    11. )
    12. class App extends React.Component {
    13. render () {
    14. const { main, sidebar } = this.props
    15. return (
    16. <div>
    17. <div className="Main">
    18. {main}
    19. </div>
    20. <div className="Sidebar">
    21. {sidebar}
    22. </div>
    23. </div>
    24. )
    25. }
    26. }
    27. class Users extends React.Component {
    28. render () {
    29. return (
    30. <div>
    31. {/* 当路径是 "/users/123" 是 `children` 会是 <Profile> */}
    32. {/* UsersSidebar 也可以获取作为 this.props.children 的 <Profile> ,
    33. 所以这有点奇怪,但你可以决定哪一个可以
    34. 继续这种嵌套 */}
    35. {this.props.children}
    36. </div>
    37. )
    38. }
    39. }
    getComponent(location, callback)

    component 一样,但是是异步的,对于 code-splitting 很有用。

    callback signature

    cb(err, component)

    1. <Route path="courses/:courseId" getComponent={(location, cb) => {
    2. // 做一些异步操作去查找组件
    3. cb(null, Course)
    4. }}/>
    getComponents(location, callback)

    component 一样,但是是异步的,对于 code-splitting 很有用。

    callback signature

    cb(err, components)

    1. <Route path="courses/:courseId" getComponent={(location, cb) => {
    2. // 做一些异步操作去查找组件
    3. cb(null, {sidebar: CourseSidebar, content: Course})
    4. }}/>
    children

    Route 可以被嵌套,this.props.children 包含了从子 route 组件创建的元素。由于这是路由设计中非常重要的部分,请参考 Route 配置。

    onEnter(nextState, replaceState, callback?)

    当 route 即将进入时调用。它提供了下一个路由的 state,一个函数重定向到另一个路径。this 会触发钩子去创建 route 实例。

    callback 作为函数的第三个参数传入时,这个钩子将是异步执行的,并且跳转会阻塞直到 callback 被调用。

    onLeave()

    当 route 即将退出时调用。

    PlainRoute

    route 定义的一个普通的 JavaScript 对象。 Router 把 JSX 的 <Route> 转化到这个对象中,如果你喜欢,你可以直接使用它们。 所有的 props 都和 <Route> 的 props 一样,除了那些列在这里的。

    Props

    childRoutes

    子 route 的一个数组,与在 JSX route 配置中的 children 一样。

    getChildRoutes(location, callback)

    childRoutes 一样,但是是异步的,并且可以接收 location。对于 code-splitting 和动态路由匹配很有用(给定一些 state 或 session 数据会返回不同的子 route)。

    callback signature

    cb(err, routesArray)

    1. let myRoute = {
    2. path: 'course/:courseId',
    3. childRoutes: [
    4. announcementsRoute,
    5. gradesRoute,
    6. assignmentsRoute
    7. ]
    8. }
    9. // 异步的子 route
    10. let myRoute = {
    11. path: 'course/:courseId',
    12. getChildRoutes(location, cb) {
    13. // 做一些异步操作去查找子 route
    14. cb(null, [ announcementsRoute, gradesRoute, assignmentsRoute ])
    15. }
    16. }
    17. // 可以根据一些 state
    18. // 跳转到依赖的子 route
    19. <Link to="/picture/123" state={{ fromDashboard: true }}/>
    20. let myRoute = {
    21. path: 'picture/:id',
    22. getChildRoutes(location, cb) {
    23. let { state } = location
    24. if (state && state.fromDashboard) {
    25. cb(null, [dashboardPictureRoute])
    26. } else {
    27. cb(null, [pictureRoute])
    28. }
    29. }
    30. }
    indexRoute

    index route。这与在使用 JSX route 配置时指定一个 <IndexRoute> 子集一样。

    getIndexRoute(location, callback)

    indexRoute 一样,但是是异步的,并且可以接收 location。与 getChildRoutes 一样,对于 code-splitting 和动态路由匹配很有用

    callback signature

    cb(err, route)

    1. // 例如:
    2. let myIndexRoute = {
    3. component: MyIndex
    4. }
    5. let myRoute = {
    6. path: 'courses',
    7. indexRoute: myIndexRoute
    8. }
    9. // 异步的 index route
    10. let myRoute = {
    11. path: 'courses',
    12. getIndexRoute(location, cb) {
    13. // 做一些异步操作
    14. cb(null, myIndexRoute)
    15. }
    16. }

    Redirect

    在应用中 <Redirect> 可以设置重定向到其他 route 而不改变旧的 URL。

    Props

    from

    你想由哪个路径进行重定向,包括动态段。

    to

    你想重定向的路径。

    query

    默认情况下,query 的参数只会经过,但如果你需要你可以指定它们。

    1. // 我们需要从 `/profile/123` 改变到 `/about/123`
    2. // 并且由 `/get-in-touch` 重定向到 `/contact`
    3. <Route component={App}>
    4. <Route path="about/:userId" component={UserProfile}/>
    5. {/* /profile/123 -> /about/123 */}
    6. <Redirect from="profile/:userId" to="about/:userId" />
    7. </Route>

    注意,在 route 层 <Redirect> 可以被放在任何地方,尽管正常的优先 规则仍适用。如果你喜欢将下一个重定向到它各自的 route 上,from 的路径会匹配到一个与 path 一样的正常路径。

    1. <Route path="course/:courseId">
    2. <Route path="dashboard" />
    3. {/* /course/123/home -> /course/123/dashboard */}
    4. <Redirect from="home" to="dashboard" />
    5. </Route>

    IndexRoute

    当用户在父 route 的 URL 时,
    Index Routes 允许你为父 route 提供一个默认的 “child”,
    并且为使<IndexLink> 能用提供了约定。

    请看 Index Routes 指南。

    Props

    与 Route 的 props 一样,除了 path

    IndexRedirect

    Index Redirects 允许你从一个父 route 的 URL 重定向到其他 route。
    它们被用于允许子 route 作为父 route 的默认 route,
    同时保持着不同的 URL。

    请看 Index Routes 指南。

    Props

    与 Redirect 的 props 一样,除了 from

    Route Components

    当 route 匹配到 URL 时会渲染一个 route 的组件。路由会在渲染时将以下属性注入组件中:

    history

    Router 的 history history。

    对于跳转很有用的 this.props.history.pushState(state, path, query)

    location

    当前的 location。

    params

    URL 的动态段。

    route

    渲染组件的 route。

    routeParams

    this.props.params 是直接在组件中指定 route 的一个子集。例如,如果 route 的路径是 users/:userId 而 URL 是 /users/123/portfolios/345,那么 this.props.routeParams 会是 {userId: '123'},并且 this.props.params 会是 {userId: '123', portfolioId: 345}

    children

    匹配到子 route 的元素将被渲染。如果 route 有已命名的组件,那么此属性会是 undefined,并且可用的组件会被直接替换到 this.props 上。

    示例
    1. render((
    2. <Router>
    3. <Route path="/" component={App}>
    4. <Route path="groups" component={Groups} />
    5. <Route path="users" component={Users} />
    6. </Route>
    7. </Router>
    8. ), node)
    9. class App extends React.Component {
    10. render() {
    11. return (
    12. <div>
    13. {/* 这可能是 <Users> 或 <Groups> */}
    14. {this.props.children}
    15. </div>
    16. )
    17. }
    18. }

    已命名的组件

    当一个 route 有一个或多个已命名的组件时,其子元素的可用性是通过 this.props 命名的。因此 this.props.children 将会是 undefined。那么所有的 route 组件都可以参与嵌套。

    示例

    1. render((
    2. <Router>
    3. <Route path="/" component={App}>
    4. <Route path="groups" components={{main: Groups, sidebar: GroupsSidebar}} />
    5. <Route path="users" components={{main: Users, sidebar: UsersSidebar}}>
    6. <Route path="users/:userId" component={Profile} />
    7. </Route>
    8. </Route>
    9. </Router>
    10. ), node)
    11. class App extends React.Component {
    12. render() {
    13. // 在父 route 中,被匹配的子 route 变成 props
    14. return (
    15. <div>
    16. <div className="Main">
    17. {/* 这可能是 <Groups> 或 <Users> */}
    18. {this.props.main}
    19. </div>
    20. <div className="Sidebar">
    21. {/* 这可能是 <GroupsSidebar> 或 <UsersSidebar> */}
    22. {this.props.sidebar}
    23. </div>
    24. </div>
    25. )
    26. }
    27. }
    28. class Users extends React.Component {
    29. render() {
    30. return (
    31. <div>
    32. {/* 如果在 "/users/123" 路径上这会是 <Profile> */}
    33. {/* UsersSidebar 也会获取到作为 this.props.children 的 <Profile> 。
    34. 你可以把它放这渲染 */}
    35. {this.props.children}
    36. </div>
    37. )
    38. }
    39. }

    Mixins

    生命周期 Mixin

    在组件中添加一个钩子,当路由要从 route 组件的配置中跳转出来时被调用,并且有机会去取消这次跳转。主要用于表单的部分填写。

    在常规的跳转中, routerWillLeave 会接收到一个单一的参数:我们正要跳转的 location。去取消此次跳转,返回 false。

    提示用户确认,返回一个提示信息(字符串)。在 web 浏览器 beforeunload 事件发生时,routerWillLeave 不会接收到一个 location 的对象(假设你正在使用 useBeforeUnload history 的增强方法)。在此之上,我们是不可能知道要跳转的 location,因此 routerWillLeave 必须在用户关闭标签之前返回一个提示信息。

    生命周期方法

    routerWillLeave(nextLocation)

    当路由尝试从一个 route 跳转到另一个并且渲染这个组件时被调用。

    arguments
    • nextLocation - 下一个 location

    History Mixin

    在组件中添加路由的 history 对象。

    注意:你的 route components 不需要这个 mixin,它在 this.props.history 中已经是可用的了。这是为了组件更深次的渲染树中需要访问路由的 history 对象。

    Methods

    pushState(state, pathname, query)

    跳转至一个新的 URL。

    arguments
    • state - location 的 state。
    • pathname - 没有 query 完整的 URL。
    • query - 通过路由字符串化的一个对象。
    replaceState(state, pathname, query)

    在不影响 history 长度的情况下(如一个重定向),用新的 URL 替换当前这个。

    参数
    • state - location 的 state。
    • pathname - 没有 query 完整的 URL。
    • query - 通过路由字符串化的一个对象。
    go(n)

    在 history 中使用 n-n 进行前进或后退

    goBack()

    在 history 中后退。

    goForward()

    在 history 中前进。

    createPath(pathname, query)

    使用路由配置,将 query 字符串化加到路径名中。

    createHref(pathname, query)

    使用路由配置,创建一个 URL。例如,它会在 pathname 的前面加上 #/ 给 hash history。

    isActive(pathname, query, indexOnly)

    根据当前路径是否激活返回 truefalse。通过 pathname 匹配到 route 分支下的每个 route 将会是 true(子 route 是激活的情况下,父 route 也是激活的),除非 indexOnly 已经指定了,在这种情况下,它只会匹配到具体的路径。

    参数
    • pathname - 没有 query 完整的 URL。
    • query - 如果没有指定,那会是一个包含键值对的对象,并且在当前的 query 中是激活状态的 - 在当前的 query 中明确是 undefined 的值会丢失相应的键或 undefined
    • indexOnly - 一个 boolean(默认:false)。

    示例

    1. import { History } from 'react-router'
    2. React.createClass({
    3. mixins: [ History ],
    4. render() {
    5. return (
    6. <div>
    7. <div onClick={() => this.history.pushState(null, '/foo')}>Go to foo</div>
    8. <div onClick={() => this.history.replaceState(null, 'bar')}>Go to bar without creating a new history entry</div>
    9. <div onClick={() => this.history.goBack()}>Go back</div>
    10. </div>
    11. )
    12. }
    13. })

    假设你正在使用 bootstrap,并且在 Tab 中想让那些 li 获得 active

    1. import { Link, History } from 'react-router'
    2. const Tab = React.createClass({
    3. mixins: [ History ],
    4. render() {
    5. let isActive = this.history.isActive(this.props.to, this.props.query)
    6. let className = isActive ? 'active' : ''
    7. return <li className={className}><Link {...this.props}/></li>
    8. }
    9. })
    10. // 如 <Link/> 一样使用它,你会得到一个包进 `li` 的锚点
    11. // 并且还有一个自动的 `active` class。
    12. <Tab href="foo">Foo</Tab>

    但我仍然在使用 Classes

    注意难道我们没有告诉你要使用 ES6 的 Classes?:)

    https://twitter.com/soprano/status/610867662797807617

    在应用中少数组件由于 History mixin 的缘故而用得不爽,此时有以下几个选项:

    • this.props.history 通过 route 组件到达需要它的组件中。
    • 使用 context
    1. import { PropTypes } from 'react-router'
    2. class MyComponent extends React.Component {
    3. doStuff() {
    4. this.context.history.pushState(null, '/some/path')
    5. }
    6. }
    7. MyComponent.contextTypes = { history: PropTypes.history }
    • 确保你的 history 是一个 module
    • 创建一个高阶的组件,我们可能用它来结束跳转和阻止 history,只是没有时间去思考所有的方法。
    1. function connectHistory(Component) {
    2. return React.createClass({
    3. mixins: [ History ],
    4. render() {
    5. return <Component {...this.props} history={this.history} />
    6. }
    7. })
    8. }
    9. // 其他文件
    10. import connectHistory from './connectHistory'
    11. class MyComponent extends React.Component {
    12. doStuff() {
    13. this.props.history.pushState(null, '/some/where')
    14. }
    15. }
    16. export default connectHistory(MyComponent)

    RouteContext Mixin

    RouteContext mixin 提供了一个将 route 组件设置到 context 中的便捷方法。这对于 route 渲染元素并且希望用 生命周期 mixin 来阻止跳转是很有必要的。

    简单地将 this.context.route 添加到组件中。

    Utilities

    useRoutes(createHistory)

    返回一个新的 createHistory 函数,它可以用来创建读取 route 的 history 对象。

    • listen((error, nextState) => {})
    • listenBeforeLeavingRoute(route, (nextLocation) => {})
    • match(location, (error, redirectLocation, nextState) => {})
    • isActive(pathname, query, indexOnly=false)

    match(location, cb)

    这个函数被用于服务端渲染。它在渲染之前会匹配一组 route 到一个 location,并且在完成时调用 callback(error, redirectLocation, renderProps)

    传给回调函数去 match 的三个参数如下:

    • error:如果报错时会出现一个 Javascript 的 Error 对象,否则是 undefined
    • redirectLocation:如果 route 重定向时会有一个 Location 对象,否则是 undefined
    • renderProps:当匹配到 route 时 props 应该通过路由的 context,否则是 undefined

    如果这三个参数都是 undefined,这就意味着在给定的 location 中没有 route 被匹配到。

    注意:你可能不想在浏览器中用它,除非你做的是异步 route 的服务端渲染。

    createRoutes(routes)

    创建并返回一个从给定对象 route 的数组,它可能是 JSX 的 route,一个普通对象的 route,或是其他的数组。

    params

    routes

    一个或多个的 RoutePlainRoute

    PropTypes

    敬请期待!