Skip to main content

🍑 React路由

先把它的官网直接丢上来 reactrouter,Web端它的相关包是 react-router-dom

BrowserRouter

路由最重要的一个组件,用于注册路由。它必须包裹所有 react-router-dom 所属的路由组件,这些组件才具有对应的路由属性。它一般是写在脚手架的最外端,也就是 index.jsx 中。

ReactDOM.render(
<BrowserRouter>
<App/>
</BrowserRouter>,
document.getElementById('root')
);

HashRouter

BrowserRouter相似,只不过它是以锚点为驱动。

  1. 底层原理不一样
  • BrowserRouter使用的是H5的history API,不兼容IE9以下版本
  • HashRouter使用的是URL的哈希值
  1. url表现形式不一样
  • BrowserRouter的路径中没有#localhost:3000/welcome
  • HashRouter的路径包含#localhost:3000/#welcome
  1. 刷新后对路由state参数的影响
  • BrowserRouter的保存在history对象中,不会丢
  • HashRouter会丢

Route

该组件监听浏览器的地址栏,不同的地址栏会匹配不同的组件,用于展示区。路由匹配并渲染时,会给component传入的组件添加 historylocationmatch属性(props)。

<Route path="/about" component={About}/>

<Link/>组件用于替代传统的<a/>,且可以在页面跳转时传递参数,用于导航区。

基本用法

push模式跳转

<Link to="/about"></Link>

也可以replace模式跳转

<Link replace to="/about"></Link>

传递params参数

一个声明(Route)接收,一个负责(Link)传。

<Route path="/welcome/:id" component={Welcome}/>
......
<Link to="/welcome/520"></Link>

传递之后的参数在 this.props.match.params 里。

class Welcome extends Component {
render(){
// params是一个对象,{id: 520}
const params = this.props.match.params;
}
}

传递search参数

它就像query参数,在浏览器地址栏?后面的数据(urlencoded编码)。Route组件无需声明接收。

<Link to="/welcome?id=520"></Link>

传递之后的参数在 this.props.location.search 里。

import qs from 'querystring'; // React脚手架已经帮忙下载好了

class Welcome extends Component {
render(){
// search是一个字符串 "?id=520"
const search = this.props.location.search;
const result = qs.parse(search.slice(1)); // 去除'?'号
// result = {id: 520};
}
}

传递state参数

Link组件的to参数稍微改动一下,增加一个state参数,同样的Route组件无需声明接收。刷新也可以保留住参数。

<Link to={{pathname: "/welcome", state: {id: 520}}}></Link>

传递之后的参数在 this.props.location.state 里。

class Welcome extends Component {
render(){
// state是一个对象 {id: 520}
// || {}
// 如果是HashRouter,history可能会丢,所以给它一个默认对象
// 如果是BrowserRouter则不受影响
const state = this.props.location.state || {};
}
}

比与<Link/>组件多一个功能。点击时会给类名加上 active ,而且 <NavLink/> 会保证只有一个导航按钮的类名拥有 active

当然如果使用的组件库不是 active,也可也认为的控制加的是其他的类名。

<NavLink activeClassName="highlight" children="跳转"/>

Switch

用于多个路由都匹配时,只展示最先被匹配的那个。如果不使用它,类似的效果就像 switch 语句的 case 不加 break

<Switch>
<Route path="/introduction" component={Article} />
<Route path="/" component={Welcome} />
</Switch>

路由匹配模式

默认的匹配方式是模糊匹配

<Link to="/home"/>    // 能
<Link to="/home/b"/> // 能
<Link to="a/home/b"/> // 否
......
<Route path="/home"/>

若想严格匹配,给<Route/>组件加一个exact

<Link to="/home"/>    // 能
<Link to="/home/b"/> // 能
<Link to="a/home/b"/> // 否
......
<Route exact path="/home"/>

Redirect

重定向组件,可以用在 Switch里,当所有路由都不匹配时,可以用作一个兜底的路由。

<Switch>
<Route path="/introduction" component={Article} />
<Route path="/welcome" component={Welcome} />
<Redirect to="/error" component={Error}/>
</Switch>

编程式路由导航

借助props中的history进行。

push跳转

this.props.history.push(`/welcome/520`);          // params        
this.props.history.push(`/welcome?id=520`); // search
this.props.history.push(`/welcome`, {id: 520}); // state

replace跳转

this.props.history.replace(`/welcome/520`);        // params
this.props.history.replace(`/welcome?id=520`); // search
this.props.history.replace(`/welcome`, {id: 520}); // state

go跳转

this.props.history.go(step);    // step是前进还是后退number类型的步数 
this.props.history.goForward(); // 前进
this.props.history.goBack(); // 后退

withRouter

用于普通组件赋予路由组件的属性(historylocationmatch

class Header extends Component {
......
}

export default withRouter(Header);