美文网首页
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