美文网首页
React Router学习之旅(二)

React Router学习之旅(二)

作者: LU7IN | 来源:发表于2017-12-17 00:14 被阅读0次
    图片.png

    我们给App添加的导航栏现在已经成功地显示在页面上了。不使用React Router,我们可以把ul做成一个组件,即Nav,然后把Nav渲染到我们的屏幕上。

    你注意到你的应用像下图中那样相互嵌套在盒子里面吗?你注意到你的URLs变成像/repos/123这样了吗?我们组件的结构就如下图所示:

    图片.png 图片.png 图片.png

    React Router接受这样把路由给结合在一起,称为结合UI。

    图片.png

    分享我们的导航

    让我们把AboutRepos组件给结合起来到App当中,并将其导航链接给分享至屏幕中去。我们需要做下面的两个步骤:

    首先,让App的路由有子节点,并将其他的路由放到该子节点当中去。

    index.js

    import React from 'react'
    import { render } from 'react-dom'
    import { Router, Route, hashHistory } from 'react-router'
    import App from './modules/App'
    import About from './modules/About'
    import Repos from './modules/Repos'
    
    render((
      <Router history={hashHistory}>
        <Route path="/" component={App}/>
        <Route path="/repos" component={Repos}/>
        <Route path="/about" component={About}/>
      </Router>
    ), document.getElementById('app'))
    

    接着我们在App当中渲染该子节点。

    moudules/App.js

    import React from 'react'
    import { Link } from 'react-router'
    
    export default React.createClass({
      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>
            {this.props.children}
          </div>
        )
      }
    })
    
    图片.png

    好了,现在点击链接而且注意到App会持续得渲染子路由组件通过this.props.children

    图片.png

    有一种方法可以让Link区别于a,那就是让链接可以动态地更换自身的风格。

    让我们看看如何用内联的方法,添加activeStyle到你的Link上。

    modules/App.js

    <li><Link to="/about" activeStyle={{ color: 'red' }}>About</Link></li>
    <li><Link to="/repos" activeStyle={{ color: 'green' }}>Repos</Link></li>
    
    图片.png

    现在我们只要用鼠标点击一下,导航栏就会变成红色了的。

    图片.png

    我们同样可以使用Class Name

    modules/App.js

    我们不必将样式写在该页面上去。让我们添加一个额外的link标签。

    index.html

    <link rel="stylesheet" href="index.css">

    图片.png

    效果如图所示:

    图片.png 图片.png

    网站中的大多数的链接不必知道他们是否是活跃的,通常只有主要的链接是需要知道的而已。将那些你不必去记住的activeClassNameactiveStyle给包裹起来。

    我们将使用一个展开的操作器,也就是三个点。使用这种方法,它会克隆我们的属性activeClassName到我们想要的组件。

    创建一个文件为NavLink.js在modules文件目录下。

    NavLink.js

    import React from 'react'
    import { Link } from 'react-router'
    
    export default React.createClass({
      render() {
        return <Link {...this.props} activeClassName="active"/>
      }
    })
    
    图片.png

    接着我们将链接换成NavLink

    modules/App.js

    import React from 'react'
    import { Link } from 'react-router'
    import NavLink from './NavLink'
    
    export default React.createClass({
      render() {
        return (
          <div>
            <h1>React Router Tutorial</h1>
            <ul role="nav">
               <li><NavLink to="/about">About</NavLink></li>
               <li><NavLink to="/repos">Repos</NavLink></li>
            </ul>
          </div>
        )
      }
    })
    
    图片.png

    现在我们点击这两个链接并不会直接跳转。

    图片.png

    URL参数

    考虑下面的URL,如上图所示。

    这些URL会匹配路由的路径,比如:

    /repos/:userName/:repoName

    参数是从:开始的:这些URL参数将会被解析以及变为可以访问的路由组件通过this.props.params[name]

    图片.png

    给路由添加参数

    让我们的应用在屏幕上去如何渲染/repos/:userName/:repoName

    首先我们需要一个组件去渲染这个路由,新建一个文件夹modules/Repo.js:

    代码如下:

    Repo.js

    import React from 'react'
    
    export default React.createClass({
      render() {
        return (
            <div>
               <h2>{this.props.params.repoName}</h2>
            </div>
            )
      }
    })
    

    index.js

    import React from 'react'
    import { render } from 'react-dom'
    import { Router, Route, hashHistory } from 'react-router'
    import App from './modules/App'
    import About from './modules/About'
    import Repos from './modules/Repos'
    import Repo from './modules/Repo'
    
    render((
      <Router history={hashHistory}>
        <Route path="/" component={App}>
          <Route path="/repos" component={Repos}/>
          <Route path="/repos/:userName/:repoName" component={Repo}/>
          <Route path="/about" component={About}/>
        </Route>
      </Router>
    ), document.getElementById('app'))
    

    Repos.js

    import React from 'react'
    import { Link } from 'react-router'
    
    export default React.createClass({
      render() {
        return (
            <div>
               <h2>Repos</h2>
    
               <ul>
                  <li><Link to="/repos/reactjs/react-router">React Router</Link></li>
                  <li><Link to="/repos/facebook/react">React</Link></li>
               </ul>
            </div>
            )
      }
    })
    
    图片.png

    现在路由路径的参数名称已经变成组件的属性了。repoNameuserName已经可以组件中通过this.props.params来访问到。

    图片.png

    注意,当我们导航到不同的仓库时,其他的导航链接是如何消失的?

    首先,将Repo路由给聚集到Repos路由下。然后在Reposthis.props.children渲染。

    图片.png 图片.png 图片.png

    动态链接

    让我们把active属性添加到NavLink上。

    modules/Repos.js

    import React from 'react'
    import { Link } from 'react-router'
    import NavLink from './NavLink'
    
    export default React.createClass({
      render() {
        return (
          <div>
            <h2>Repos</h2>
            <ul>
              <li><NavLink to="/repos/reactjs/react-router">React Router</NavLink></li>
              <li><NavLink to="/repos/facebook/react">React</NavLink></li>
            </ul>
    
            {this.props.children}
          </div>
        )
      }
    })
    
    图片.png 图片.png

    索引路由

    当我们通过/访问一个空白的界面,我们想要渲染一个Home组件在这个空白的界面。我们创建这个组件并试着如何去渲染它。

    代码太多我就偷懒不贴上来了,看图就好:

    图片.png 图片.png 图片.png

    打开localhost:8080,显示如下:

    图片.png

    IndexRoute我看得不是很懂,所以下面的内容我是搬运阮一峰老师的:

    下面的例子,你会不会觉得有一点问题?

        <Router>
          <Route path="/" component={App}>
            <Route path="accounts" component={Accounts}/>
            <Route path="statements" component={Statements}/>
          </Route>
        </Router>
    

    上面代码中,访问根路径/,不会加载任何子组件。也就是说,App组件的this.props.children,这时是undefined

    因此,通常会采用{this.props.children || <Home/>}这样的写法。这时,Home明明是AccountsStatements的同级组件,却没有写在Route中。

    IndexRoute就是解决这个问题,显式指定Home是根路由的子组件,即指定默认情况下加载的子组件。你可以把IndexRoute想象成某个路径的index.html

        <Router>
          <Route path="/" component={App}>
            <IndexRoute component={Home}/>
            <Route path="accounts" component={Accounts}/>
            <Route path="statements" component={Statements}/>
          </Route>
        </Router>
    

    现在,用户访问/的时候,加载的组件结构如下。

        <App>
          <Home/>
        </App>
    

    这种组件结构就很清晰了:App只包含下级组件的共有元素,本身的展示内容则由Home组件定义。这样有利于代码分离,也有利于使用React Router提供的各种API。

    注意,IndexRoute组件没有路径参数path

    总结一下,IndexRoute就是默认加载显示的那个组件。

    相关文章

      网友评论

          本文标题:React Router学习之旅(二)

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