• 升级指南
    • 0.13.3 -> 1.0.0
      • 渲染
      • Location
      • Route 配置
      • NotFound 路由
      • Redirect 路由
      • Links
        • path / params
        • “active” 类
        • 链接到默认路由
      • RouteHandler
      • Navigation Mixin
      • State mixin
      • Scrolling
      • willTransitionTowillTransitionFrom
      • 我们将持续更新
    • 0.13.2 -> 0.13.3
    • 0.12.x -> 0.13.2 (PLEASE SKIP THIS)
    • 0.11.x -> 0.12.0
    • 0.10.x -> 0.11.x
      • React 0.12
      • <Routes/> and starting the router
      • this.props.activeRouteHandler() -> <RouteHandler/>
      • this.props.params and this.props.query
      • ActiveState -> State, and methods too
      • CurrentPath -> State
      • Route addHandlerKey prop
      • <Routes onError={fn}/>
      • Router.renderRoutesTo*
      • Route Props Passed to Handlers
    • 0.9.x -> 0.10.x
    • 0.7.x -> 0.9.x
      • ActiveState mixin isActive
      • <Routes onActiveStateChange/> -> <Routes onChange />
      • . in params support
      • transition.retry()
      • Returning promises from transition hooks
      • preserveScrollPosition -> scrollBehavior
      • RouteStore
      • Router.transitionTo, replaceWith, goBack
      • <Routes onTransitionError onAbortedTransition/>
      • ActiveState lifecycle method updateActiveState removed
      • AsyncState mixin removed
    • 0.7.x -> 0.8.x
    • 0.6.x -> 0.7.x
    • 0.5.x -> 0.6.x
      • Path Matching
      • Link params
      • Dynamic Segments, keys, and lifecycle methods
    • 0.4.x -> 0.5.x
    • 0.3.x -> 0.4.x
    • 0.2.x -> 0.3.x
    • 0.1.x -> 0.2.x

    升级指南

    更多关于 API 升级的细节,请参阅更新日志,可以查看所有相关的 commitissue

    0.13.3 -> 1.0.0

    感谢你的耐心等待,终于迎来了这次重大变更。虽然表面上看来只是更新了一些 API,而实际上为了适用于更大型的应用场景,我们几乎重写了整个代码库。新的 API 提供了按需载入路由和组件、基于 session 的路由匹配、服务端渲染、整合 redux 和 relay 库,等等等等。

    现在,我们来对比一下新旧 API 的区别。

    渲染

    1. // v0.13.x
    2. Router.run(routes, (Handler) => {
    3. React.render(<Handler/>, el);
    4. })
    5. // v1.0
    6. React.render(<Router>{routes}</Router>, el)
    7. // 类似这样:
    8. React.render((
    9. <Router>
    10. <Route path="/" component={App}/>
    11. </Router>
    12. ), el);
    13. // 当然也可以这样
    14. React.render(<Router routes={routes}/>, el)

    Location

    现在,location 被叫做 history(它会映射 location)。你需要从 history 包导入它们,而不是 react-router。

    1. // v0.13.x
    2. Router.run(routes, Router.BrowserHistory, (Handler) => {
    3. React.render(<Handler/>, el);
    4. })
    5. // v1.0
    6. import createBrowserHistory from 'history/lib/createBrowserHistory'
    7. let history = createBrowserHistory()
    8. React.render(<Router history={history}>{routes}</Router>, el)

    如果没有指定 history 的类型(就像上面),那你要注意下在升级到 1.0.0 后的异常行为。一个并非你所定义的名为 _kquerystring 和路由所需的 hash 一并出现在了 URL 的后面。类似这样:?_k=umhx1s

    这是有意为之的,它是 createHashHistory 部分的内容(也是当你没有指定时,默认的 history 方法)。你可以在这里了解更多关于它的特性,详细的文档在这里。

    Route 配置

    你依旧可以像上面那样嵌套路由,路径同样也会从父组件继承而来,不过属性名称有变化。

    1. // v0.13.x
    2. <Route name="about" handler={About}/>
    3. // v1.0
    4. <Route path="about" component={About}/>

    具名路由已被移除(现在可以查看相关的讨论)

    NotFound 路由

    NotFound 确实搞晕了好多人,搞不清楚是 API 中找不到资源还是没有可匹配的路由。而实际上它仅仅是一个简单的 * 路径,我们已经彻底移除了它。

    1. // v0.13.x
    2. <NotFoundRoute handler={NoMatch}/>
    3. // v1.0
    4. <Route path="*" component={NoMatch}/>

    Redirect 路由

    • 没有增加参数
    • from 必须使用绝对路径
    1. // v0.13.x
    2. <Redirect from="some/where/:id" to="somewhere/else/:id" params={{id: 2}}/>
    3. // v1.0
    4. // 可以像上面一样正常工作,除了去掉 params 参数,将它们放到了路径当中
    5. <Redirect from="/some/where/:id" to="/somewhere/else/2"/>

    path / params

    1. // v0.13.x
    2. <Link to="user" params={{userId: user.id}}>Mateusz</Link>
    3. // v1.0
    4. // 由于具名路由被移除,链接改为完成路径,你不再需要获取每个参数的名称。同时,字符串插值新特性非常棒。
    5. // 注意,query 并没有改变。
    6. <Link to={`/users/${user.id}`}>Mateusz</Link>

    “active” 类

    在 0.13.x link 组件会默认添加 “active” 类,你可以通过 activeClassName 重写它,或者提供 activeStyle。而事实上,绝大多数 link 并不需要它,并且检测起来(目前来看)还是很昂贵的。

    Link 不会默认添加 “active” 类,你可以选择增加一个;如果没有 activeClassName 或者 activeStyle,即便被激活,也不会去检测 link

    1. // v0.13.x
    2. <Link to="about">About</Link>
    3. // v1.0
    4. <Link to="/about" activeClassName="active">About</Link>

    链接到默认路由

    由于具名路由被移除,如果默认路由是 /,指向 /link 就会一直处于激活状态。所以,我们介绍的 IndexLink 仅仅是当默认路由处于激活状态时。

    注意:DefaultRoute 已经废弃。

    1. // v0.13.x
    2. // 配置路由
    3. <Route path="/" handler={App}>
    4. <DefaultRoute name="home" handler={Home}/>
    5. <Route name="about" handler={About}/>
    6. </Route>
    7. // 仅仅在 home 被激活是它才会被激活,在 about 激活时则不会
    8. <Link to="home">Home</Link>
    9. // v1.0
    10. <Route path="/" component={App}>
    11. <IndexRoute component={Home}/>
    12. <Route path="about" component={About}/>
    13. </Route>
    14. // 仅仅在 home 被激活是它才会被激活,在 about 激活时则不会
    15. <IndexLink to="/">Home</IndexLink>

    RouteHandler

    RouteHandler 被移除。现在 Router 可以基于激活的路由自动填充组件的 this.props.children

    1. // v0.13.x
    2. <RouteHandler/>
    3. <RouteHandler someExtraProp={something}/>
    4. // v1.0
    5. {this.props.children}
    6. {React.cloneElement(this.props.children, {someExtraProp: something })}

    Navigation Mixin

    如果你正在用 Navigation mixin,那么可以使用 History mixin 代替。

    1. // v0.13.x
    2. var Assignment = React.createClass({
    3. mixins: [ Navigation ],
    4. navigateAfterSomethingHappened () {
    5. this.transitionTo('/users', { userId: user.id }, query);
    6. // this.replaceWith('/users', { userId: user.id }, query);
    7. }
    8. })
    9. // v1.0
    10. var Assignment = React.createClass({
    11. mixins: [ History ],
    12. navigateAfterSomethingHappened () {
    13. // 现在的路由构建于 rackt/history 之上,并且它是路由中用于导航的第一类 API
    14. this.history.pushState(null, `/users/${user.id}`, query);
    15. // this.history.replaceState(null, `/users/${user.id}`, query);
    16. }
    17. })

    下面的所有 Navigation 方法同样可以在 history 对象中找到,主要的区别还是移除了 params 以及路由名称,仅仅剩下路径名称。

    v0.13 v1.0
    go(n) go(n)
    goBack() goBack()
    goForward() goForward()
    makeHref(routeName, params, query) createHref(pathname, query)
    makePath(routeName, params, query) createPath(pathname, query)

    State mixin

    1. // v0.13.x
    2. var Assignment = React.createClass({
    3. mixins: [ State ],
    4. foo () {
    5. this.getPath()
    6. this.getParams()
    7. // 等...
    8. }
    9. })
    10. // v1.0
    11. // 如果是一个路由组件...
    12. <Route component={Assignment} />
    13. var Assignment = React.createClass({
    14. foo () {
    15. this.props.location // 包含路径信息
    16. this.props.params // 包含参数
    17. this.props.history.isActive
    18. }
    19. })
    20. // 如果不是一个路由组件,你需要借助 context 将 location 经组件树传递下去。
    21. // 我们也可能提供一个更加高阶组件来帮助你完成这个,不过现在还不行。
    22. // 下面看一下借助 context 我们还可以传递哪些信息。
    23. var Assignment = React.createClass({
    24. contextTypes: {
    25. location: React.PropTypes.object
    26. },
    27. foo () {
    28. this.context.location
    29. }
    30. })

    下面的表格展示了用于替换 State mixin 的方法。如果是一个组件路由的话,可以通过 this.props 获取到

    v0.13 (this) v1.0 (this.props)
    getPath() location.pathname+location.search
    getPathname() location.pathname
    getParams() params
    getQuery() location.search
    getRoutes() routes
    isActive(to, params, query) history.isActive(pathname, query, onlyActiveOnIndex)

    下面是另外一张表格,展示了在路由组件下借助 this.context 替换 State mixin 的方法。

    v0.13 (this) v1.0 (this.context)
    getPath() location.pathname+location.search
    getPathname() location.pathname
    getQuery() location.search
    isActive(to, params, query) history.isActive(pathname, query, onlyActiveOnIndex)

    注意,在 v1.0 中并非所有的 State 特性都可以通过 context 访问到。比如,通过 context 不能获取到 params

    Scrolling

    在 0.13.x 中,有两个接口用于还原滚动位置。我们意识到可以在最外层组件创建一个更优雅的实现,并且很快就要去完成,在最终的 1.0 release 之前。不过没必要受到以前路由的约束。

    willTransitionTowillTransitionFrom

    现在,路由定义了该行为:

    1. // v0.13.x
    2. var Home = React.createClass({
    3. statics: {
    4. willTransitionTo (transition, params, query, callback) {
    5. }
    6. willTransitionFrom (component, transition, params, query, callback) {
    7. }
    8. }
    9. })
    10. // v1.0
    11. <Route
    12. component={Home}
    13. onEnter={(location, replaceWith) => {}}
    14. onLeave={() => {}}
    15. />

    想要取消一个“transition from”,请参阅跳转前确认部分。

    我们将持续更新

    有很多旧的 API 已被我们舍弃,烦请详读新的文档,帮助我们完善它。感谢!

    0.13.2 -> 0.13.3

    Like many others in the community, we misunderstood the “mixins are
    going away” sentiment. Mixins, along with React.createClass are not
    going away any time soon, and definitely not until ES6 classes have
    better answers to replace what mixins do (like decorators).

    So, don’t access context, use the mixins, sorry for the churn, we know
    it can be frustrating.

    Upgrade path from 0.13.2 to 0.13.3 is to put your code back to how
    it was in 0.12.x. The context stuff will still work, so you can do it
    incrementally.

    0.12.x -> 0.13.2 (PLEASE SKIP THIS)

    SKIP THIS UPGRADE AND GO STRAIGHT TO 0.13.3

    0.13.3 has the same API as 0.12.x, so please upgrade to 0.13.3 and
    skip the 0.13.0-0.13.2 stuff and leave your code alone :)

    React introduced the ability to use ES6 classes for component
    definitions, which has the side-effect of mixins not being “the thing”
    anymore. Our mixins like State and Navigation just proxied calls to
    some methods on an undocumented feature of React called context, that
    in turn called methods on the router instance under the hood.

    Without mixins we needed a way for you to get access to these methods.
    We decided the simplest solution was to stop hiding the router instance
    and just put the whole thing on context.

    You can think about context as values that are floating around a render
    tree that parent components (Handler in the Router.run callback) can
    explicitly define and descendent components can explicitly ask for. The
    stuff on context doesn’t show up in a component unless you ask for it.

    Note: You can still use our mixins, you’ll just get a deprecation warning.

    1. // 0.12.x
    2. var Foo = React.createClass({
    3. mixins: [ Router.State ],
    4. render: function () {
    5. var id = this.getParams().id;
    6. var searchTerm = this.getQuery().searchTerm;
    7. // etc. ...
    8. }
    9. });
    10. // 0.13.x w/o ES6 fanciness
    11. var Foo = React.createClass({
    12. contextTypes: {
    13. router: React.PropTypes.func
    14. },
    15. render: function () {
    16. var router = this.context.router;
    17. var id = router.getCurrentParams().id;
    18. var searchTerm = router.getCurrentQuery().searchTerm;
    19. // etc.
    20. }
    21. });
    22. // 0.13.x w/ ES6 fanciness
    23. class Foo extends React.Component {
    24. render () {
    25. var { router } = this.context;
    26. var id = router.getCurrentParams().id;
    27. var searchTerm = router.getCurrentQuery().searchTerm;
    28. // etc.
    29. }
    30. }
    31. Foo.contextTypes = {
    32. router: React.PropTypes.func
    33. };

    Most of the time we prefer to just pass the state down the props tree
    and not mess with context:

    1. Router.run(routes, (Handler, state) => {
    2. React.render(<Handler {...state}/>, document.body);
    3. });
    4. // and then when rendering route handlers, keep passing it down
    5. <RouteHandler {...this.props}/>
    6. // and then in your methods you have what you need on props
    7. var id = this.props.params.id;
    8. var searchTerm = this.props.query.searchTerm;

    0.11.x -> 0.12.0

    transition.wait was removed, you now use a callback instead:

    1. // 0.11.x
    2. var SomeHandler = React.createClass({
    3. statics: {
    4. willTransitionTo (transition) {
    5. transition.wait(somePromise());
    6. }
    7. }
    8. });
    9. // 0.12.0
    10. var SomeHandler = React.createClass({
    11. statics: {
    12. willTransitionTo (transition, params, query, callback) {
    13. somePromise().then(callback);
    14. }
    15. }
    16. });

    0.10.x -> 0.11.x

    The router changed a lot in this release. While you won’t have to
    change too much of your app, you will have to change it in a lot of
    places. The fundamental change is that you, rather than the router, get
    to have control of your view instances.

    If you find anything is missing from this list, please open an issue and
    we will get it added here ASAP.

    React 0.12

    You must upgrade to 0.12.x before you can use version 0.11.x of the
    router.

    <Routes/> and starting the router

    <Routes/> is gone, there is a new API that gives you complete control
    of your views.

    1. // 0.10.x
    2. var routes = (
    3. <Routes location="history">
    4. <Route handler={App}>
    5. <Route name="dashboard" handler={Dashboard}/>
    6. </Route>
    7. </Routes>
    8. );
    9. React.render(routes, el);
    10. // 0.11.x
    11. var routes = (
    12. <Route handler={App}>
    13. <Route name="dashboard" handler={Dashboard}/>
    14. </Route>
    15. );
    16. Router.run(routes, Router.HistoryLocation, function (Handler) {
    17. React.render(<Handler/>, el);
    18. });
    19. // or default to hash location
    20. Router.run(routes, function (Handler) {
    21. React.render(<Handler/>, el);
    22. });

    this.props.activeRouteHandler() -> <RouteHandler/>

    1. // 0.10.x
    2. var Something = React.createClass({
    3. render: function () {
    4. return (
    5. <div>
    6. <this.props.activeRouteHandler />
    7. </div>
    8. );
    9. }
    10. });
    11. // 0.11.x
    12. var RouteHandler = Router.RouteHandler;
    13. var Something = React.createClass({
    14. render: function () {
    15. return (
    16. <div>
    17. <RouteHandler />
    18. </div>
    19. );
    20. }
    21. });

    this.props.params and this.props.query

    They are no longer available on props, use the State mixin.

    1. // 0.10.x
    2. var Something = React.createClass({
    3. render: function () {
    4. var name = this.props.params.name;
    5. var something = this.props.query.something;
    6. // ...
    7. }
    8. });
    9. // 0.11.x
    10. // pass it down the view hierarchy to get the same lifecycle hooks to
    11. // trigger as before
    12. Router.run(routes, function (Handler, state) {
    13. React.render(<Handler params={state.params} query={state.query} />, el);
    14. // make sure to `<RouteHandler {...this.props}/>` to continue
    15. // passing it down the hierarchy
    16. });
    17. // or use the `State` mixin
    18. var Something = React.createClass({
    19. mixins: [ Router.State ],
    20. render: function () {
    21. var name = this.getParams().name;
    22. var something = this.getQuery().something;
    23. // ...
    24. }
    25. });
    26. // Also, if you're using a flux-style app, you can trigger a "transition"
    27. // action in the `run` callback with the params/query in the payload, then
    28. // subscribe in your handlers to the store that grabs the data.

    ActiveState -> State, and methods too

    This mixin’s name has changed, and all of its methods that had the word
    active in it, too. For example, getActiveParams() becomes getParams().

    1. // v0.10.x
    2. var Something = React.createClass({
    3. mixins: [ Router.ActiveState ],
    4. render: function () {
    5. var name = this.getActiveParams().name;
    6. // ...
    7. }
    8. });
    9. // v0.11.x
    10. var Something = React.createClass({
    11. mixins: [ Router.State ]
    12. render: function () {
    13. var name = this.getParams().name;
    14. // ...
    15. }
    16. });

    CurrentPath -> State

    You can find this.getPath() on the Router.State mixin.

    1. // v0.10.x
    2. var Something = React.createClass({
    3. mixins: [ Router.CurrentPath ],
    4. render: function () {
    5. var path = this.getCurrentPath();
    6. // ...
    7. }
    8. });
    9. // v0.11.x
    10. var Something = React.createClass({
    11. mixins: [ Router.State ],
    12. render: function () {
    13. var path = this.getPath();
    14. // ...
    15. }
    16. });

    Route addHandlerKey prop

    This option has been removed, you will need to add handler keys
    yourself:

    1. // 0.10.x
    2. <Route handler={App}>
    3. <Route addHandlerKey={true}/>
    4. </Route>
    5. // 0.11.x
    6. var App = React.createClass({
    7. mixins: [ Router.State ],
    8. getHandlerKey: function () {
    9. // this will all depend on your needs, but here's a typical
    10. // scenario that's pretty much what the old prop did
    11. var childDepth = 1; // have to know your depth
    12. var childName = this.getRoutes()[childDepth].name;
    13. var id = this.getParams().id;
    14. var key = childName+id;
    15. return key;
    16. },
    17. render: function () {
    18. return (
    19. <div>
    20. <RouteHandler key={this.getHandlerKey()} />
    21. </div>
    22. );
    23. }
    24. });

    <Routes onError={fn}/>

    <Routes/> is gone, instead create a router with your error handler as
    an option:

    1. // 0.10.x
    2. <Routes onError={fn}>
    3. // ...
    4. </Routes>
    5. // 0.11.x
    6. var router = Router.create({
    7. onError: fn,
    8. // ...
    9. });
    10. router.run(callback);

    Router.renderRoutesTo*

    These methods have been removed because you, not the router, are in
    control of rendering.

    1. // v0.10.x
    2. Router.renderRoutesToString(routes, path, function (html) {
    3. // do something with `html`
    4. });
    5. // v0.11.x
    6. Router.run(routes, path, function (Handler) {
    7. var html = React.renderToString(<Handler/>);
    8. });

    Route Props Passed to Handlers

    In 0.10.x you could add props to your route that would make their way
    down to your handlers. While convenient, conflating routes with their
    handlers was confusing to a lot of folks.

    To get the same effect, you can either create your handlers with a
    function and close over the information you need, or simply define those
    properties on your handlers.

    1. // 0.10.x
    2. <Route name="users" foo="bar" handler={Something}/>
    3. var Something = React.createClass({
    4. render () {
    5. return <div>{this.props.name} {this.props.foo}</div>
    6. }
    7. });
    8. // 0.11.x
    9. // close over technique
    10. <Route name="users" handler={makeSomething("users", "bar")}/>
    11. function makeSomething(name, foo) {
    12. return React.createClass({
    13. render () {
    14. return <div>{name} {foo}</div>
    15. }
    16. });
    17. }
    18. // handler definition technique
    19. <Route name="users" handler={Something}/>
    20. var Something = React.createClass({
    21. foo: "bar",
    22. name: "users",
    23. render () {
    24. return <div>{this.name} {this.foo}</div>
    25. }
    26. });

    0.9.x -> 0.10.x

    Nothing changed, this was simply React 0.12.0 compatibility. Note,
    your code needs to use the React 0.11.x API for things to work, there
    will be lots of warnings in the console.

    0.7.x -> 0.9.x

    ActiveState mixin isActive

    isActive is now an instance method.

    1. // 0.7.x
    2. var SomethingActive = React.createClass({
    3. mixins: [ActiveState],
    4. render: function () {
    5. var isActive = SomethingActive.isActive(...);
    6. }
    7. });
    8. // 0.9.x
    9. var SomethingActive = React.createClass({
    10. mixins: [ActiveState],
    11. render: function () {
    12. var isActive = this.isActive(...);
    13. }
    14. });

    <Routes onActiveStateChange/> -> <Routes onChange />

    1. // 0.7.x
    2. <Routes onActiveStateChange={fn} />
    3. function fn(nextState) {}
    4. // 0.9.x
    5. <Routes onChange={fn} />
    6. function fn() {
    7. // no arguments
    8. // `this` is the routes instance
    9. // here are some useful methods to get at the data you probably need
    10. this.getCurrentPath();
    11. this.getActiveRoutes();
    12. this.getActiveParams();
    13. this.getActiveQuery();
    14. }

    . in params support

    . used to be a delimiter like /, but now it’s a valid character in
    your params.

    transition.retry()

    transition.retry() used to use transitionTo, creating a new history
    entry, it now uses replaceWith.

    1. // 0.7.x
    2. React.createClass({
    3. login: function () {
    4. // ...
    5. transition.retry();
    6. }
    7. });
    8. // 0.9.x
    9. React.createClass({
    10. mixins: [Navigation],
    11. login: function () {
    12. // ...
    13. this.transitionTo(transition.path);
    14. }
    15. });

    Returning promises from transition hooks

    Transition hooks are now sync, unless you opt-in to async with
    transition.wait(promise).

    1. // 0.7.x
    2. React.createClass({
    3. statics: {
    4. willTransitionTo: function (transition) {
    5. return somePromise();
    6. }
    7. }
    8. });
    9. // 0.9.x
    10. React.createClass({
    11. statics: {
    12. willTransitionTo: function (transition) {
    13. transition.wait(somePromise());
    14. }
    15. }
    16. });

    preserveScrollPosition -> scrollBehavior

    preserveScrollPosition was totally broken and should have been named
    perverseScrollPosition.

    There are now three scroll behaviors you can use:

    • 'browser'
    • 'scrollToTop'
    • 'none'

    browser is the default, and imitates what browsers do in a typical
    page reload scenario (preserves scroll positions when using the back
    button, scrolls up when you come to a new page, etc.) Also, you can no
    longer specify scroll behavior per <Route/> anymore, only <Routes/>

    1. <Routes scrollBehavior="scrollToTop"/>

    RouteStore

    This was not a public module, but we know some people were using it.
    It’s gone now. We have made getting at the current routes incredibly
    convenient now with additions to the ActiveState mixin.

    Router.transitionTo, replaceWith, goBack

    These methods have been moved to mixins.

    1. var Router = require('react-router');
    2. // 0.7.x
    3. React.createClass({
    4. whenever: function () {
    5. Router.transitionTo('something');
    6. Router.replaceWith('something');
    7. Router.goBack();
    8. }
    9. });
    10. // 0.9.x
    11. var Navigation = Router.Navigation;
    12. React.createClass({
    13. mixins: [Navigation],
    14. whenever: function () {
    15. this.transitionTo('something');
    16. this.replaceWith('something');
    17. this.goBack();
    18. }
    19. });

    <Routes onTransitionError onAbortedTransition/>

    These were removed, there is no upgrade path in 0.9.0 but we will have
    something soon. These weren’t intended to be used.

    ActiveState lifecycle method updateActiveState removed

    We didn’t actually need this. Just use this.isActive(to, params, query).

    AsyncState mixin removed

    There is no upgrade path. Just use comoponentDidMount to request
    state. This was some groundwork for server-side rendering but we are
    going a different direction now (using props passed in to route
    handlers) so we’ve removed it.

    0.7.x -> 0.8.x

    Please don’t upgrade to 0.8.0, just skip to 0.9.x.

    0.8.0 had some transient mixins we didn’t intend to document, but had
    some miscommunication :(. If you were one of three people who used some
    of these mixins and need help upgrading from 0.8.0 -> 0.9.x find us on
    freenode in #rackt or open a ticket. Thanks!

    0.6.x -> 0.7.x

    The package root modules were removed. Please import modules from the
    Router default export.

    1. // 0.6.x
    2. var Link = require('react-router/Link');
    3. // 0.7.x
    4. var Router = require('react-router');
    5. var Link = Router.Link;

    0.5.x -> 0.6.x

    Path Matching

    Paths that start with / are absolute and work exactly as they used to.
    Paths that don’t start with / are now relative, meaning they extend
    their parent route.

    Simply add / in front of all your paths to keep things working.

    1. <!-- 0.5.x -->
    2. <Route path="/foo">
    3. <Route path="bar"/>
    4. </Route>
    5. <!-- 0.6.x -->
    6. <Route path="/foo">
    7. <Route path="/bar"/>
    8. </Route>

    Though you may want to embrace this new feature:

    1. <!-- 0.5.x -->
    2. <Route path="/course/:courseId">
    3. <Route path="/course/:courseId/assignments"/>
    4. <Route path="/course/:courseId/announcements"/>
    5. </Route>
    6. <!-- 0.6.x -->
    7. <Route path="/course/:courseId">
    8. <Route path="assignments"/>
    9. <Route path="announcements"/>
    10. </Route>

    Also . is no longer matched in dynamic segments.

    1. <!-- 0.5.x -->
    2. <Route path="/file/:filename" />
    3. <!-- 0.6.x -->
    4. <Route path="/file/:filename.?:ext?" />
    5. <!--
    6. or for a looser match to allow for multiple `.` note that the data
    7. will be available on `this.props.params.splat` instead of
    8. `this.props.params.filename`
    9. -->
    10. <Route path="/file/*" />

    Links should now pass their params in the params property, though the
    old behavior will still work, you should update your code soon because
    it will be removed by v1.0

    1. // 0.5.x
    2. <Link to="user" userId="123"/>
    3. // 0.6.x
    4. <Link to="user" params={{userId: "123"}}/>

    Dynamic Segments, keys, and lifecycle methods

    If you have dynamic segments and are depending on getInitialState,
    componentWillMount, or componentDidMount to fire between transitions
    to the same route—like users/123 and users/456—then you have two
    options:

    • add addHandlerKey={true} to your route and keep the previous
      behavior (but lose out on performance), or
    • implement componentWillReceiveProps.
    1. // 0.5.x
    2. <Route handler={User} path="/user/:userId"/>
    3. // 0.6.x
    4. <Route handler={User} path="/user/:userId" addHandlerKey={true} />
    5. // 0.5.x
    6. var User = React.createClass({
    7. getInitialState: function () {
    8. return {
    9. user: getUser(this.props.params.userId);
    10. }
    11. }
    12. });
    13. // 0.6.x
    14. var User = React.createClass({
    15. getInitialState: function () {
    16. return this.getState();
    17. },
    18. componentWillReceiveProps: function (newProps) {
    19. this.setState(this.getState(newProps));
    20. },
    21. getState: function (props) {
    22. props = props || this.props;
    23. return {
    24. user: getUser(props.params.userId)
    25. };
    26. }
    27. });

    0.4.x -> 0.5.x

    We brought back <Routes/>.

    1. // 0.4.x
    2. var routes = (
    3. <Route handler={App} location="history">
    4. <Route name="about" handler="about"/>
    5. </Route>
    6. );
    7. // 0.5.x
    8. var routes = (
    9. <Routes location="history">
    10. <Route handler={App}>
    11. <Route name="about" handler="about"/>
    12. </Route>
    13. </Routes>
    14. );

    0.3.x -> 0.4.x

    NPM users should point their apps to react-router instead of
    react-nested-router. Make sure to npm prune!

    0.2.x -> 0.3.x

    • React 0.11.x is now required.
    • this.props.activeRoute became this.props.activeRouteHandler()
    1. // 0.2.x
    2. var App = React.createClass({
    3. render: function () {
    4. return (
    5. <div>
    6. {this.props.activeRoute}
    7. </div>
    8. );
    9. }
    10. });
    11. // 0.3.x
    12. var App = React.createClass({
    13. render: function () {
    14. // now you can send extra props to the active route handler
    15. // and use the new jsx syntax
    16. // <this.props.activeRouteHandler extraProp={something}/>
    17. return (
    18. <div>
    19. {this.props.activeRouteHandler()}
    20. </div>
    21. );
    22. }
    23. });

    0.1.x -> 0.2.x

    The Router function was removed.

    1. // 0.1.x
    2. var router = Router(routes);
    3. router.renderComponent(element);
    4. // 0.2.x
    5. React.renderComponent(routes, element);