跳到主要内容

react-routerV3-V4区别

React-Router-V3


import React from "react";
import { render } from "react-dom";
import { Router, Route, IndexRoute, Link, browserHistory } from "react-router";

const PrimaryLayout = props =>
<div className="primary-layout">
<header>Our React Router 3 App</header>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/user">User</Link>
</li>
</ul>
<main>
{props.children}
</main>
</div>;

const HomePage = () => <h1>Home Page</h1>;
const UsersPage = () => <h1>User Page</h1>;

const App = () =>
<Router history={browserHistory}>
<Route path="/" component={PrimaryLayout}>
<IndexRoute component={HomePage} />
<Route path="/user" component={UsersPage} />
</Route>
</Router>;

render(<App />, document.getElementById("root"));

V3的嵌套方式

<IndexRoute component={HomePage} /> PrimaryLayout组件的this.props.children,这时是undefined。 IndexRoute就是解决这个问题,显式指定Home是根路由的子组件,即指定默认情况下加载的子组件 使用 {props.children} 来嵌套组件,嵌套出来的结果如下

<PrimaryLayout>
<HomePage/>
<PrimaryLayout/>

React-Router-V4

V4 中就不复存在的点

  • 集中式 router
  • 通过 <Route> 嵌套,实现 Layout 和 page 嵌套
  • Layout 和 page 组件 是作为 router 的一部分

包容性路由

在前面的例子中,你可能已经注意到了 exact 这个属性。那么它是什么呢?V3 的路由规则是“排他性”的,这意味着只有一条路由将获胜。V4 的路由默认为“包含”的,这意味着多个 <Route> 可以同时进行匹配和渲染。

“默认路由”和“未找到”

尽管在 v4 中已经没有 <IndexRoute> 了,但可以使用 <Route exact> 来达到同样的效果。如果没有路由解析,则可以使用 <Switch><Redirect> 重定向到具有有效路径的默认页面(如同我对本示例中的 HomePage 所做的),甚至可以是一个“未找到页面”。

对路由的简单理解

实现满足url改变不去发送http请求拉取新的资源,就可以实现SPA 然后用一个事件监听函数监测路由的改变,然后根据路由调用不同的组件来渲染页面

比如Route

这种相当于注册一个事件,的url发生改变的时候,上层的Router会监听到,并更新渲染整个下层,下层的route满足/PropsButton匹配,就去发布渲染PropsButton组件,有点发布订阅的感觉(我也不知能不能怎么说,先这么理解一哈

<Route path="/PropsButton" component={PropsButton} />

嵌套的一些路由

路由是一层一层的渲染

比如现在在Hello组件里写了<Route path="/box" component={Box} />

我们进入hello页面,点击 <NavLink to="/box">box</NavLink>,或者在其他页面想跳转/box路由,你会发现什么都没有

因为路由是Hello组件里注册,你必须先报Hello组件渲染才能看到box

感觉Route组件好像就是包裹我们注册的组件一样,它并不占用DOM节点(我们只需要关注注册组件的样式即可

一个路由渲染多个组件的样式问题

比如下面我们想让两个路由渲染的组件并排,只需要给个公共父节点即可操作

  <div style={{display:'flex'}}>
<Route path="/PropsButton" component={PropsButton} />
<Route path="/PropsButton" component={ComplexSelector} />
</div>

ReactRouter路由传递参数

params

<Route path='/user/:name' component={UserPage}></Route>
this.props.history.push("/user/sam");
 this.props.params.name

query

query方式可以传递任意类型的值,但是页面的URL也是由query的值拼接的,URL很长且是明文传输。

优点:刷新页面不会掉参数 缺点:不安全,没有加密

// 跳转
this.props.history.push({
pathname: '/user',
query: data,
});
// 取值
this.props.location.query

state

state方式类似于post,依然可以传递任意类型的数据,而且可以不以明文方式传输。

this.props.history.push({
pathname: '/user',
state: data,
})

解决页面返回陷入循环 replace

我们可以用this.props.history.replace来解决或者是router.replace

它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。

场景:比如用户从首页->上传图片页面->图片编辑页面->完成编辑跳到上传图片页面

如果这是我们手机用自带的返回是回不去主页的,又会跳到编辑页面

这里history会增加三条记录,如果觉得图片不行反复编辑的话就会产生更多的记录,更回不去

所以我们把:上传图片页面->图片编辑页面->完成编辑跳到上传图片页面 这两步的跳转都改为replace,就相当于上传界面和编辑界面公用一条记录一样,调用原生返回直接能返回首页