加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

react-router使用教程

发布时间:2020-12-15 05:13:05 所属栏目:百科 来源:网络整理
导读:安装命令 npm install -S react-router 基本用法 使用时,路由器Router就是React的一个组件,Router组件本身只是个容器,真正的路由要通过Route组件定义 import React from 'react';import ReactDOM from 'react-dom';import {Router,Route,hashHistory} fro

安装命令

npm install -S react-router

基本用法

使用时,路由器Router就是React的一个组件,Router组件本身只是个容器,真正的路由要通过Route组件定义

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

import App from './App.jsx';
import About from './About.jsx';

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

路由模式

Router组件的history属性,用来监听浏览器地址栏的变化,并将URL解析成一个地址对象,供React Router匹配,history一个可以设置三个值

  • browserHistory
  • hashHistory
  • createMemoryHistory

如果设为browserHistory,浏览器显示的路径是 example.com/some/path,背后调用的是浏览器的Histtory API.

注意:使用browserHistory时需要对服务器改造,否则用户直接向服务器请求某个子路由,会显示找不到网页404错误,如果开发服务器是webpack-dev-server 加上--history-api-fallback参数就可以了,如下在package.json中,其他服务器的配置请参考 https://github.com/ReactTraining/react-router/blob/master/docs/guides/Histories.md#configuring-your-server

"scripts": {
    "dev": "webpack-dev-server --history-api-fallback --hot","build": "webpack --progress --hide-modules"
 },

如果设为hashHistory,路由将通过URL的hash部分#切换,URL的形式类似 example.com/#/some/path

createMemoryHistory 主要用于服务器渲染,它创建一个内存中的history对象,不与浏览器URL互动。

const history = createMemoryHistory(location)

嵌套路由

Route组件还可以嵌套

ReactDOM.render(
	<Router history={browserHistory}>
		<Route path="/"  component={Layout}>
			<Route path="/index" component={App}/>
			<Route path="/about" component={About}/>
		</Route>
	</Router>,document.getElementById('app'))

上面代码中,用户访问/index或/about时候会先加载Layout组件,然后在Layout组件内部加载App或Abot,为此Layout组件需要加个 {this.props.children}

import React from "react"

export default React.createClass({
	render(){
		return (
			<div>
			<ul>
				<li><Link to="index">Index</Link></li>
				<li><Link to="about">About</Link></li>
			</ul>
			{this.props.children}
			</div>
		)
	}
})

上面代码中,{this.props.children} 代表子组件 子路由也可以不写在Router组件里面,单独传入Router组件的routers属性

import React from 'react';
import ReactDOM from 'react-dom';
import {Router,hashHistory,browserHistory,createMemoryHistory} from 'react-router';

import Layout from './Layout.jsx';
import App from './App.jsx';
import About from './About.jsx';

let routes = <Route component={Layout}>
	<Route path="/" component={App} />
	<Route path="/about" component={About} />
</Route>	

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

path属性

Route组件的path属性指定路由的匹配规则,这个属性是可以省略,这样的话,不管路径是否匹配,总是会加载指定组件。

<Route path="home" component={Layout}>
	<Route path="index" component={App} />
	<Route path="about(/:name)" component={About} />
</Route>

上面的例子中当用户访问/home/about/map 的时候,会加载下面的组件

<Layout>
		<About />
	</Layout>

如果省略外层Route的path参数,写成下面的样子

<Route component={Layout}>
	<Route path="index" component={App} />
	<Route path="about/:name" component={About} />
</Route>

现在访问/about/test的时候会加载下面的组件

<Layout>
	<About />
</Layout>

通配符

path属性可以使用通配符

<Route path="/hello/:name"> 匹配 /hello/michael 
<Route path="/hello(/:name)> 匹配 /hello | /hello/test
<Route path="/hello/*.*> 匹配 /hello/a.jpg
<Route path="/hello/*> 匹配 /hello/  | /hello/test
<Route path="/**/*.jpg> 匹配 /hello/a.jpg | /hello/path/to/a.jpg

通配符规则如下

  • :paramName 匹配URL的一个部分,知道遇到下一个/、?、#为止,这个路径参数可以通过this.props.params.paramName取出
  • () 表示URL的这个部分是可选的
  • * 匹配任意字符,知道模式里面的下一个字符为止,匹配方式是非贪婪模式。
  • ** 匹配任意字符,知道下一个 /、?、# 为止,匹配方式是贪婪模式。

path 属性也可以使用相对路径(不以/开头),匹配时就会相对于父组件的路径,可以参考上一节的例子。嵌套路由如果想摆脱这个规则,可以使用绝对路由。 路由匹配规则是从上到下执行,一旦发现匹配,就不再匹配其余的规则了

<Route path="/hello" component="Hello">
<Route path="/hello" component="About">

上面的代码中,路径/hello同时匹配两个规则,第二个规则不会生效。 设置路径参数时,需要特别小心这一点。

<Route>
	<Route path="/:userName/:id" component="Hello">
	<Route path="/about/me" component="About"> 
</Route>

上面的代码中,用户访问 /about/me 的时候永远不会触发第二个路由规则,因为匹配到第一个规则时候就匹配上了,不会向下走了,因此 带参数的路径一般要写在路由规则的底部。

此外,URL的查询字符串 /foo?bar=baz,可以用 this.props.location.query.bar 获取

IndexRoute 组件

IndexRoute组件是为了解决默认情况下根路由的子组件问题的

<Router history={hashHistory}>
	<Route path="/" component={Layout}>
		<IndexRoute component={Index} />
		<Route path="app" component={App} />
		<Route path="about(/:name)" component={About} />
	</Route>
</Router>

上面代码中,访问根路径 / 会加载Index组件到Layout组件的this.props.children

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

Redirect 组件

Redirect组件用于路由的跳转,即用户访问一个路由,会自动跳转到另一个路由

<Route path="/" component={Layout}>
	<Redirect from="/foo" to="/404" />
	<Route path="404" component={U404} />
	<Route path="app" component={App} />
	<Route path="about(/:name)" component={About} />
</Route>

现在访问/foo,就会自动跳转到/404

IndexRedirect 组件

IndexRedirect 组件用于访问根路由的时候,讲用户重定向到某个子路由

<Route path="/" component={Layout}>
	<IndexRedirect to="/404" />
	<Route path="404" component={U404} />
	<Route path="app" component={App} />
	<Route path="about(/:name)" component={About} />
</Route>

上面代码中,用户访问根路径时,将自动重定向到子路由中

Link

Link 组件用于取代<a>元素,生成一个链接,允许用户点击后跳转到另一个路由。它基本上就是<a>元素的React版本,可以接收Router的状态。

<ul>
	<li><Link to="/">Index</Link></li>
	<li><Link to="app">App</Link></li>
	<li><Link to="about/ggg">About</Link></li>
</ul>

如果希望当前的路由与其他路由有不同样式,这时可以使用Link组件的activeStyle属性

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

上面代码中,当前页面的链接会红色显示。

另一种做法是,使用activeClassName 指定当前路由的Class.

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

上面代码中,当前页面的链接会红色显示。

Router组件之外,导航到路由页面,可以使用浏览器的History API,像下面这样写。

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

或者这样

this.context.router.push('/some/path')

IndexLink

如果链接到根路由/,不要使用Link组件,而要使用IndexLink组件。

这是因为对于根路由来说,activeStyleactiveClassName会失效,或者说总是生效,因为/会匹配任何子路由,而IndexLink组件会使用路径的精确匹配

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

上面代码中,根路由只会在精确匹配时,才会变成红色

另一种方法是使用Link组件的 onlyActiveOnIndex属性,也能达到同样效果。

<Link to="/" activeStyle={{color:'red'}} onlyActiveOnIndex={true}>Index</Link>

实际上,IndexLink 就是对Link组件的onlyActiveOnIndex属性的包装

路由的钩子

每个路由都有Enter和Leave钩子,用户进入或离开该路由时触发。

上面的例子中,用户进入/app的时候会触发onEnter钩子,用户离开/app的时候会触发onLeave钩子,详细例子请看下面

import React from 'react';
import ReactDOM from 'react-dom';
import {Router,IndexRoute,hashHistory} from 'react-router';

import Layout from './Layout.jsx';
import App from './App.jsx';
import Index from './Index.jsx';
import About from './About.jsx';
import NotFound from './NotFound.jsx';

const beforeRouter = (nextState,replace)=>{
	console.log("beforeRouter",nextState,replace)
}

const afterRouter = (nextState,replace)=>{
	console.log("afterRouter",replace)
}

ReactDOM.render(
	<Router history={hashHistory}>
		<Route path="/" component={Layout}>
			<IndexRoute component={Index} />
			<Route path="app" component={App} onEnter={beforeRouter} onLeave={afterRouter} />
			<Route path="about(/:name)" component={About} />
			<Route path="*" component={NotFound} />
		</Route>
	</Router>,document.getElementById('app'))

本文摘自阮一峰的博客

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读