Autumn_Ning_Blog
Autumn_Ning_Blog copied to clipboard
React Router V4 入坑指南
React Router v4出来很久了,你们觉得它好用么?
思维上的转变
在我看来,ReactRouter V4虽然已经出来很久了,但是并没有在前端圈内掀起热潮,当我从原来的V3版本切换到了现在的V4版本之后,用的非常不顺心,不仅仅是它的API进行了颠覆式的改变,更值得去改变的而是V3 => V4理念上的改变————遵循一切都是组件的思维,React Router V4提供的Route Link Switch等都是组件。
我们原来写router的配置的时候,一般都会把所有的配置写在一个文件内,来进行管理路由,但是在V4版本的ReactRouter中,我们不能再使用这样的思维,不然,再复杂的页面的路由处理上会非常的蛋疼(心里苦)。
原来的V3版本的ReactRouter中,我们可以根据Route的嵌套关系来进行路由之间的嵌套,然后在使用this.props.children来直接引入到Component/Containers中即可,但是在V4版本中,就不能直接通过这种方式来使用了。
// V3
<Route path="/" component={Page}>
<Route path="app" component={App}>
<Route path="create" component={Create} />
</Route>
</Route>
// V4
<Router>
<Layout> //自己定义的组件
<Switch>
<Route path="/some-path" component={SomeComponent} />
</Switch>
</Layout>
</Router>
以及原来的动态的路由的方式也变了,在V3版本中,我们直接通过browserHistory.push的方法 来进行动态的路由的跳转即可,但是在V4版本中,我们就不能这么用了,而必须要通过withRouter高阶组件的方式去进行路由的跳转
// V3
import browserHistory from 'react-router';
export function addProduct(props) {
return dispatch =>
axios.post(`xxx`, props, config)
.then(response => {
browserHistory.push('/cart'); //这里
});
}
// V4
import React from "react";
import {withRouter} from "react-router-dom";
class MyComponent extends React.Component {
...
myFunction() {
this.props.history.push("/some/Path");
}
...
}
export default withRouter(MyComponent);
一个实际的需求
假设现在需要有三个路由,一个登陆,一个首页,一个创建订单,登录页面是一个单独的页面,没有和其他页面共有任何组件,首页和创建订单页共有Header Nav等组件,只有页面的大肚子中间部分是内容不同的。那么要保证在首页和订单页切换的过程中,确保Header Nav等公共组件的不会重新卸载和挂载。
这种需求在实际上,应该是一个比较实用的场景,在使用V3版本的ReactRouter中我们应该很快就能够想到路由的配置,但是在V4版本中,如果还一直抱着this.props.chidren这种思维去想,以及因为V4规定一个Router下只能有一个子元素,来进行路由的配置就会很蛋疼,所以在V4的使用过程中,一定要抛弃原来的思维,要把它看成是一个普通的组件来看待,当然,有些大的路由配置还是建议放在一起进行统一的管理
所以,给出下面我对这个的实现
// routers.js
// ...
<Router>
<Switch>
<Route path="/index" component={App} />
<Route exact path="/login" component={Login} />
<Redirect from="/" to="/index" />
</Switch>
</Router>
// ...
// App.js
// ...
class App extends Component {
render() {
const user = this.props.user
return (
<div className="App">
<Header
user={user}
/>
<Nav />
<Switch>
<Route exact path="/index/create" render={() => <div>创建项目</div>}></Route>
<Route render={() => <div>首页</div>}></Route>
</Switch>
</div>
)
}
}
// ...
如果你有什么更好的解决方案 请留言,谢谢!