美文网首页
react-router学习整理

react-router学习整理

作者: 张延伟 | 来源:发表于2017-11-01 19:20 被阅读86次

这篇文章是整理自己学习react-router的一些简单用法和学习资料整理,用作自己的备忘录同时分享。

入门学习

官方示例

基础用法

将官方示例克隆下来,运行命令执行起来。
首先添加一个路由:打开入口js文件index.js

// render(<App/>, document.getElementById('app'))
render(<Router/>, document.getElementById('app'))

Router是一个组件,也就是react-router,改写代码:

render( 
    <Router history={hashHistory}>
        <Route path="/" component={App}/>
    </Router> 
,document.getElementById('app'))

现在我们看到和启动前一样的页面,我们可以试着多加几个路由。
新添加两个组件

  • modules/About.js
  • modules/Repos.js
// modules/About.js
import React from 'react'

export default React.createClass({
  render() {
    return <div>About</div>
  }
})

新添加两个路由

render( 
    <Router history={hashHistory}>
        <Route path="/" component={App}/>
        <Route path="/repos" component={Repos}/>
        <Route path="/about" component={About}/>
    </Router> 
,document.getElementById('app'))

Route组件定义了URL路径与组件的对应关系。
上面代码中,用户访问/repos(比如http://localhost:8080/#/repos)时,加载Repos组件;访问/about(http://localhost:8080/#/about)时,加载About组件。

Link

Link组件用于取代<a>元素,生成一个链接,允许用户点击后跳转到另一个路由。
编辑modules/App.js

import { Link } from 'react-router'

export default React.createClass({
  render() {
    return <div>
      <ul role="nav">
        <li><Link to="/about">About</Link></li>
        <li><Link to="/repos">Repos</Link></li>
      </ul>
    </div>
  }
})

嵌套路由

之前在app上我们添加了两个链接,相当于导航的功能,但是导航应该在每个页面都应该有。我们的应用就像盒子,一个装一个,我们的链接也是一层一层往下的,假如给定url:/repos/123,我们的组件可能就像这样:

<App>       {/*  /          */}
  <Repos>   {/*  /repos     */}
    <Repo/> {/*  /repos/123 */}
  </Repos>
</App>

react的链接和我们的组件(UI)是一致的,链接和UI组件的加载是一个层级关系,3级链接就会依次加载三个路由的组件。
下面我们来实现公共导航:
首先我们书写嵌套路由:

render( 
    <Router history={hashHistory}>
        <Route path="/" component={App}>
            {/* make them children of `App` */}
            <Route path="/repos" component={Repos}/>
            <Route path="/about" component={About}/>
        </Route>
    </Router> 
,document.getElementById('app'))

组件的嵌套关系,就像父子关系,有孩子就有父,嵌套内的路由是外面一层的children,我们需要把这个子组件放在父组件对应的位置:

// modules/App.js
// ...
  render() {
    return (
      <div>
        <h1>React Router Tutorial</h1>
        <ul role="nav">
          <li><Link to="/about">About</Link></li>
          <li><Link to="/repos">Repos</Link></li>
        </ul>

        {/* add this */}
        {this.props.children}

      </div>
    )
  }
// ...

现在看页面,就是链接切换时一直在顶部。只是替换了不同的子组件,像这样:

// at /about
<App>
  <About/>
</App>

// at /repos
<App>
  <Repos/>
</App>

有了导航,我想给对应导航添加当前的样式呢,react-router提供了activeStyleactiveClassName,直接添加内联样式和添加类名来定义链接当前样式。
每次写当前样式都需要加一个active,有点麻烦,也不一定我们都记得,我们可以在Link上在封装一层,作为导航链接。

// modules/NavLink.js
import React from 'react'
import { Link } from 'react-router'

export default React.createClass({
  render() {
    return <Link {...this.props} activeClassName="active"/>
  }
})

现在我们就可以这样使用:

// modules/App.js
import NavLink from './NavLink'

// ...

<li><NavLink to="/about">About</NavLink></li>
<li><NavLink to="/repos">Repos</NavLink></li>

路由参数

路由路劲:paramName后的url会被作为参数,值可以在组件中解析this.props.params[name],我们试试在示例中添加参数来理解一下:

render( 
    <Router history={hashHistory}>
        <Route path="/" component={App}>
            <Route path="/repos" component={Repos}/>
            <Route path="/about" component={About}/>
            <Route path="/repo/:userName/:repoName" component={Repo}/>
        </Route>
    </Router> 
,document.getElementById('app'))

然后新建一个组件:

import React from 'react'

export default React.createClass({
  render() {
    return (
      <div>
        <p>第一个链接参数{this.props.params.userName}</p>
        <p>第二个链接参数{this.props.params.repoName}</p>
      </div>
    )
  }
})

然后在链接上加一个链接试试:

<li><NavLink to="/repo/zhang/123">带参数的链接</NavLink></li>
参数

路由中的参数名称会成为对应组件的属性名称。

IndexRoute

我们可以通过IndexRoute设置一个默认加载的组件。
比如我们需要给应用添加一个首页,我们添加一个默认加载的组件:

import React from 'react'

export default React.createClass({
  render() {
    return <div>Home</div>
  }
})

然后运用IndexRoute添加默认加载的组件:

render( 
    <Router history={hashHistory}>
        <Route path="/" component={App}>
            <IndexRoute component={Home}/>
            <Route path="/repos" component={Repos}/>
            <Route path="/about" component={About}/>
            <Route path="/repo/:userName/:repoName" component={Repo}/>
        </Route>
    </Router> 
,document.getElementById('app'))

现在在http://localhost:8080/不仅会加载App组件,也会加载Home组件。

IndexLink

看看我们的例子,现在我们没有连接可以回到首页,我们试着添加一个连接到首页:

<li><NavLink to="/">Home</NavLink></li>     

然而这个Home连接一直在当前状态,也就是一直是红色状态。因为/是所有根路径,所有的路径都会匹配它,所以他一直是红色状态。react-router提供了IndexLink来解决这个问题,用这个试试:

<li><IndexLink to="/" activeStyle={{ color: 'red' }}>Home</IndexLink></li>

history

history学习资料

高级用法

动态路由

对于大型应用来说,一个首当其冲的问题就是所需加载的 JavaScript 的大小。程序应当只加载当前渲染页所需的 JavaScript以及组件。
Route可以定义getChildRoutegetIndexRoutegetComponents这几个函数。他们都是异步执行的,并且只在需要时才被调用。React Router 会逐渐的匹配 URL 并只加载该 URL 对应页面所需的路径配置和组件。

const CourseRoute = {
  path: 'course/:courseId',

  getChildRoutes(location, callback) {
    require.ensure([], function (require) {
      callback(null, [
        require('./routes/Announcements'),
        require('./routes/Assignments'),
        require('./routes/Grades'),
      ])
    })
  },

  getIndexRoute(location, callback) {
    require.ensure([], function (require) {
      callback(null, require('./components/Index'))
    })
  },

  getComponents(location, callback) {
    require.ensure([], function (require) {
      callback(null, require('./components/Course'))
    })
  }
}

相关文章

网友评论

      本文标题:react-router学习整理

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