react-router 学习

前端之家收集整理的这篇文章主要介绍了react-router 学习前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

参考资料

官网github;

github官网给出的tutorial;

tutorial

rendering-a-route

Rendering a Route

hashHistory

You should get the same screen as before,but this time with some junk in the URL. We're usinghashHistory--it manages the routing history with the hash portion of the url. It's got that extra junk to shim some behavior the browser has natively when using real urls. We'll change this to use real urls later and lose the junk,but for now,this works great because it doesn'trequire any server-side configuration.

说明hashHistory管理的是url的hash部分,通过hash值匹配url

navigating-with-link

Navigating with Link

Link

Perhaps the most used component in your app isLink.

说明Link. 也是一个组件,通过他方便我们找到路由其他部分

import { Link } from 'react-router'
<li><Link to="/about">About</Link></li>

nested-routes

nested-routes

Nested UI and Nested URLs

Have you ever noticed your app is just a series of Boxes inside Boxes inside Boxes? Have you also noticed your URLs tend to be coupled to that nesting? For example given this url,/repos/123,our components would probably look like this:

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

And our UI something like:

+-------------------------------------+
         | Home Repos About                    | <- App
         +------+------------------------------+
         |      |                              |
Repos -> | repo |  Repo 1                      |
         |      |                              |
         | repo |  Boxes inside Boxes          |
         |      |  inside Boxes ...            | <- Repo
         | repo |                              |
         |      |                              |
         | repo |                              |
         |      |                              |
         +------+------------------------------+

React Router embraces this by letting you nest your routes,which automatically becomes nested UI.

说明:嵌套ui(路由,router可以理解为一个组件)

<Route path="/" component={App}>
      {/* make them children of `App` */}
      <Route path="/repos" component={Repos}/>
      <Route path="/about" component={About}/>
    </Route>

Next,render children inside ofApp.

// 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>
    )
  }
// ...

Alright,now go click the links and notice that theAppcomponent continues to render while the child route's component gets swapped around asthis.props.children:)

说明:嵌套组件配置之后,App就可以管理子组件Repos,About了。

{this.props.children}显示的就是url对应的子组件的内容

index.js只是配置路由关系而已,不处理应用的呈现关系。呈现关系是由url决定的。

比如http://localhost:8080/,应用找的是app这个组件,然后根据这个组件的route,呈现自己的层级关系。

The best way to build large things is to stitch small things together.大而化小,化繁为简。

What happens if you move theAboutroute outside ofApp?,如果将about放回原处。

app不控制about组件。点击about连接还是页面跳转

Active Links

05-active-links

Active Styles

<li><Link to="/about" activeStyle={{ color: 'red' }}>About</Link></li>

说明:多个样式,使用json格式

<li><Link to="/about" activeStyle={{color:'red',fontSize:'30px'}}>About</Link></li>

注意font-size变成驼峰。或者使用

<li><Link to="/about" activeStyle={{"color":'red',"font-size":'30px'}}>About</Link></li>

双引号key格式

Active Class Name

<li><Link to="/about" activeClassName="active">About</Link></li>

Nav Link Wrappers

navLink封装。

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"/>
  }
})

Now you can go change your links toNavLinks.

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

// ...

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

Params

06-params

URL Params

These URLs would match a route path like this:

/repos/:userName/:repoName

说明:The parts that start with:are URL parameters whose values will be parsed out and made available to route components onthis.props.params[name].

通过this.props.params[name].取得参数。例如应用中配置的<Route path="/repos/:userName/:repoName" component={Repo}/>那么可以根据{this.props.params.repoName}找到对应的repoName,例如

http://localhost:8080/#/repos/reactjs/react-router,得到的结果就是react-router,如果{this.props.params.userName}得到的就是reactjs了。

More Nesting

07-more-nesting

nest theReporoute under theReposroute. Then go renderthis.props.childreninRepos.

// index.js
// ...
<Route path="/repos" component={Repos}>
  <Route path="/repos/:userName/:repoName" component={Repo}/>
</Route>
// Repos.js
// ...
<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>
  {/* will render `Repo.js` when at /repos/:userName/:repoName */}
  {this.props.children}
</div>

说明:定义route层级关系之后,利用this.props.children显示子组件内容.如上定义了repos>repo之后,在父组件repos里面,利用this.props.children就可以显示(预览)子组件的内容了。

Active Links

Notice how both the/reposlink up top and the individual repo links are both active? When child routes are active,so are the parents.

说明:子组件active之后,父组件如果设置了active,也相应的会被active了。

Index Routes

08-index-routes

When we visit/in this app it's just our navigation and a blank page.

if we have any children inApp,and if not,renderHome:

说明:根目录/指定。

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

// ...
<div>
  {/* ... */}
  {this.props.children || <Home/>}
</div>
//...

如果url有渲染子组件,那么就显示子组件内容。如果没有就显示home组件。如

url:http://localhost:8080/#/?_k=sn17mk 为根目录,后面没有带hash,那么显示内容

如果有hash值的话,显示就是对应的子组件内容了。

另一种处理方式,就是代码和结构分离,利用配置的方式去指定。

indexRoute

<Route path="/" component={App}>
      {/* add it here,as a child of `/` */}
      <IndexRoute component={Home}/>
      <Route path="/about" component={About}/>
    </Route>

Index Links

09-index-links

如果使用普通的自定义navlink的方式。

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

这种方式,当url为/xx的时候。/根目录也会被active,使用下面的两种方式就可以避免了。

IndexLink

// App.js
import { IndexLink } from 'react-router'

// ...
<li><IndexLink to="/" activeClassName="active">Home</IndexLink></li>

使用这个IndexLink标签而不是使用自定义的NavLink标签是为了防止activeClass 找父route的时候对/根目录都active了。

onlyActiveOnIndex

这种方式也可以达到上面效果

<li><Link to="/" activeClassName="active" onlyActiveOnIndex={true}>Home</Link></li>

这两种方式都可以

clean-urls

10-clean-urls

The URLs in our app right now are built on a hack: the hash. It's the default because it will always work,but there's a better way.

Modern browsers let JavaScript manipulate the URL without making an http request,so we don't need to rely on the hash (#) portion of the url to do routing,but there's a catch (we'll get to it later).

可以不以来hash来制定url,现代浏览器可以制定url,不需要请求http服务。

Configuring Browser History

browserHistory

Open upindex.jsand importbrowserHistoryinstead ofhashHistory.

// index.js
// ...
// bring in `browserHistory` instead of `hashHistory`
import { Router,Route,browserHistory,IndexRoute } from 'react-router'

render((
  <Router history={browserHistory}>
    {/* ... */}
  </Router>
),document.getElementById('app'))

利用browserHistoryinstead ofhashHistory.来指定页面跳转

使用browserHistory之后链接地址就不需要hash值了,为常见的链接了。客户端js可以改变url显示,不需要向服务器发送请求。

但是如果刷新会出现

因为这个链接是客户端链接,可以理解为是一个假连接,或者是hash的一种变换。

Configuring Your Server

Your server needs to deliver your app no matter what URL comes in,because your app,in the browser,is manipulating the URL. Our current server doesn't know how to handle the URL.

The Webpack Dev Server has an option to enable this. Open uppackage.jsonand add--history-api-fallback.

"start": "webpack-dev-server --inline --content-base . --history-api-fallback"

We also need to change our relative paths to absolute paths inindex.htmlsince the URLs will be at deep paths and the app,if it starts at a deep path,won't be able to find the files.

<!-- index.html -->
<!-- index.css -> /index.css -->
<link rel="stylesheet" href="/index.css">

<!-- bundle.js -> /bundle.js -->
<script src="/bundle.js"></script>

Stop your server if it's running,thennpm startagain. Look at those clean URLs :)

需要配置package.json,让服务器知道如何处理请求,另外也要修改index.html里面的index.css,bundle.js路径,需要将相对路径--》绝对路径

刷新可以,深层次链接的话,比如点repos的子连接,刷新也可以了。★★★★★html里面的js,css一定要改相对路径为绝对路径

productionish-server

Production-ish Server

None of this has anything to do with React Router

react router与服务器无关。为了更接近实际,

配置生产环境。

注意看文档是怎么配置的。

注意,这里配置运行环境的时候window要使用cmd命令窗口,不能使用powershell,或者使用类unix的bash环境(比如git bash),就可以直接使用命令了。

NODE_ENV=production npm start
# For Windows users:
# SET "NODE_ENV=production" && npm start

按照示例代码,把index.html和index.css都要挪到public文件夹(正式环境发布文件夹,压缩后的代码都会放在这里。)

其他代码也是按照示例去修改

navigating

Navigating

Navigating Programatically

While most navigation happens withLink,you can programmatically navigate around an application in response to form submissions,button clicks,etc.

链接操作。再提交表单,或者点击事件的时候页面url的变迁有两种方式

1.使用 browserHistory

browserHistory.push(path)

这种方式有个弊端就是链接必须是history认识的,不然没有办法作用。比如在demo中输入了userName:2,pwd:3;url:http://localhost:8080/repos/2/3 url就没有作用了。页面跳转,history找不到这个url。显示为空了。

2.

You can also use therouterthatRouterprovides on "context". First,you ask for context in the component,and then you can use it:

export default React.createClass({

  // ask for `router` from context
  contextTypes: {
    router: React.PropTypes.object
  },// ...

  handleSubmit(event) {
    // ...
    this.context.router.push(path)
  },// ..
})

使用router提供的context上下文对象。使用这种方式,即使上面的url也可以正常显示

server-rendering

Server Rendering

server渲染主要通过服务端利用模板,渲染给客户端。注意数据同步的问题。

相关配置,直接参考doc文档。

doc

Guides and API docs

要点参考

reactjs101;

RouteConfiguration

RouteConfiguration

Decoupling the UI from the URL

分离ui和url配置。

<Router>
    <Route path="/" component={App}>
      {/* Show the dashboard at / */}
      <IndexRoute component={Dashboard} />
      <Route path="about" component={About} />
      <Route path="inBox" component={InBox}>
        <Route path="messages/:id" component={Message} />
      </Route>
    </Route>
  </Router>

上面的配置inBox下面再配置message组件,ui和url融合在一起。

如果要分离的话使用下面的方式,这样类似分模块,可以一层一层细分route

<Router>
    <Route path="/" component={App}>
      <IndexRoute component={Dashboard} />
      <Route path="about" component={About} />
      <Route path="inBox" component={InBox} />

      {/* Use /messages/:id instead of /inBox/messages/:id */}
      <Route component={InBox}>
        <Route path="messages/:id" component={Message} />
      </Route>
    </Route>
  </Router>

这种方式访问的话,就不能使用/inBox/messages/:id 访问方式了,而是要使用/messages/123456,这样的方式去访问了。要解决这个问题,需要用到下面的Preserving urls

Preserving URLs

redirect

Wait a minute ... we just changed a URL!That's not cool. Now everyone who had a link to/inBox/messages/5has abroken link. :(

Not to worry. We can use a<Redirect>to make sure that URL still works!

前面ui和url分离了。导致url需要变化,如果我们不想改变url访问路径,这里使用redirect来处理。

<Router>
    <Route path="/" component={App}>
      <IndexRoute component={Dashboard} />
      <Route path="about" component={About} />

      <Route path="inBox" component={InBox}>
        {/* Redirect /inBox/messages/:id to /messages/:id */}
        <Redirect from="messages/:id" to="/messages/:id" />
      </Route>

      <Route component={InBox}>
        <Route path="messages/:id" component={Message} />
      </Route>
    </Route>
  </Router>

Now when someone clicks on that link to/inBox/messages/5they'll automatically be redirected to/messages/5. 原文链接:https://www.f2er.com/react/305892.html

猜你在找的React相关文章