react 路由 react-router@3.2.1

react路由,4.x的差异还是比较大,暂时还是3.x的版本

安装:

npm install -S react-router@3.x

配置:

import { Router, Route, hashHistory } from 'react-router';

<Router history={hashHistory}>{/*browserHistory、hashHistory、createMemoryHistory*/}
    <Route exact path="/" component={App}> {/*exact 表示精确匹配*/}
        <IndexRoute component={Home}/>{/*显式指定Home是根路由的子组件,即指定默认情况下加载的子组件。*/}
        <IndexRedirect to="/welcome" />{/*IndexRedirect组件用于访问根路由的时候,将用户重定向到某个子组件。*/}
        <Route path="welcome" component={Welcome} />
        <Route path="/repos" component={Repos}/>
        <Route path="/about/(:id)" component={About}/>
        <Route path="inbox" component={Inbox}>
          {/*<Redirect>组件用于路由的跳转,即用户访问一个路由,会自动跳转到另一个路由。*/}
          {/* 从 /inbox/messages/:id 跳转到 /messages/:id */}
          {/* :id 获取-> this.props.params.id*/}
          <Redirect from="messages/:id" to="/messages/:id" />
        </Route>
    </Route> 
   <Route path="*" component={Page404}></Route>
</Router>

app组件:

export default React.createClass({
 let baseUrl = this.props.match.url;{/*获得当前路由,即 / ,对于页面可维护性是十分重要的*/}
  render() {
    return (
        <div>
            <ul role="nav">
              <IndexLink to="/" activeClassName="active">Home</IndexLink>{/*默认页*/}
              <li><Link to=`/${baseUrl}/about` activered'}}>About</Link></li>
              <li><Link to="/repos" activeClassName="active">Repos</Link></li>
         <li><Link to={{ pathname: '/hello', query: { name: 'ryan' } }}> Hello </Link></li>
         <li><Link to={`/my/${myId}/info`}>点击</Link></li>
         <li><Link to={{pathname:"/select", hash:'#ahash', query:{foo: 'bar', boo:'boz'}, state:{data:'miao'}  }} activeClassName="GlobalNav-active">精选</Link></li>
            </ul>
            <div>
              {this.props.children} {/*this.props.children属性就是子组件*/}
            </div>
        </div>
    )    
  }
})

path属性:

<Route path="/hello/:name">
// 匹配 /hello/michael
// 匹配 /hello/ryan

<Route path="/hello(/:name)">
// 匹配 /hello
// 匹配 /hello/michael
// 匹配 /hello/ryan

<Route path="/files/*.*">
// 匹配 /files/hello.jpg
// 匹配 /files/hello.html

<Route path="/files/*">
// 匹配 /files/ 
// 匹配 /files/a
// 匹配 /files/a/b

<Route path="/**/*.jpg">
// 匹配 /files/hello.jpg
// 匹配 /files/path/to/file.jpg

path属性也可以使用相对路径(不以/开头),匹配时就会相对于父组件的路径。路由匹配规则是从上到下执行,一旦发现匹配,就不再其余的规则了。

编程式导航:

hashHistory

import { hashHistory } from 'React-router'
... ...
hashHistory.push('mine')
//传参
hashHistory.push({
    pathname: 'good/details/'+this.state.id,//与路由表中配置相对应,
        query: {
            title:value.title,
            name:value.name
        },
    })      
... ...

接收参数:

this.props.params.id

this.props.location.query.title
this.props.location.query.name

此外:

browserHistory

import { browserHistory } from 'react-router';
... ...
browserHistory.push('/some/path');

context对象

class Example extends React.Component {
    constructor(props, context) {
        super(props, context);
        this.context.router; // it works
    }
    ... ...
    handleSubmit(event) {
        this.context.router.push(path)
    },    
}
//必须显示声明
Example.contextTypes = {
    router:  React.PropsTypes.object 
}

路由钩子:

onEnter与onLeave

onEnter钩子替代<Redirect>组件。

<Route path="inbox" component={Inbox}>
  <Route
    path="messages/:id"
    onEnter={
      ({params}, replace) => replace(`/messages/${params.id}`)
    } 
  />
</Route>

onEnter钩子还可以用来做认证。

const requireAuth = (nextState, replace) => {
    if (!auth.isAdmin()) {
        // Redirect to Home page if not an Admin
        replace({ pathname: '/' })
    }
}
export const AdminRoutes = () => {
  return (
     <Route path="/admin" component={Admin} onEnter={requireAuth} />
  )
}

当用户离开一个路径的时候,跳出一个提示框,要求用户确认是否离开。

const Home = withRouter(
  React.createClass({
    componentDidMount() {
      this.props.router.setRouteLeaveHook(
        this.props.route, 
        this.routerWillLeave
      )
    },

    routerWillLeave(nextLocation) {
      // 返回 false 会继续停留当前页面,
      // 否则,返回一个字符串,会显示给用户,让其自己决定
      if (!this.state.isSaved)
        return '确认要离开?';
    },
  })
)

上面代码中,setRouteLeaveHook方法为Leave钩子指定routerWillLeave函数。该方法如果返回false,将阻止路由的切换,否则就返回一个字符串,提示用户决定是否要切换。