banner
他山之石

他山之石

React Router V4学习笔记

React Router 现在已经是 React 开发单页应用必备技能,自升级 V4 版本以来,许多核心 API 都进行了重写,践行路由即组件的概念,本文是我学习 React Router V4 以来的一些总结。

image

介绍#

React-Router V4 是 react-router 的一次重大更新,许多核心 API 都已改变,使用 react-router4 不需要对路由进行集中式配置,react-router 4 的核心是一切皆组件。

react-router 4 一共被拆分为三个包:react-router、react-router-dom、react-router-native,react-router 提供了 React Router 的核心路由功能,包括 Router, Route, Switch 等,但是我们不会直接使用它。react-router-dom 和 react-router-native 提供在特定运行环境下的路由组件。如果你需要开发在浏览器中运行的 Web 应用,则应该安装 react-router-dom。同样,如果你需要开发 React Native 应用程序,则应该安装 react-router-native。这两者都将安装 react-router 作为依赖项。

react-router-dom#

react-router 使用 react-router-dom 作为浏览器端的路由,提供了 BrowserRouter,Route,Link 等 api, 通过 DOM 的事件控制路由。在 Web 开发过程中,我们更多是使用 react-router-dom。本文的讨论也仅限于 react-router-dom。

安装

npm install react-router-dom --save

使用#

Router#

react-router4 的使用首先需要选择 Router,Router 用于包裹在应用最外层。Router 有两种类型:HashRouter 和 BrowserRouter,其表现方式也有所不同,使用时需要区分。

HashRouter 与 BrowserRouter#

从表面区分 HashRouter 和 BrowserRouter 的方法就是 HashRouter 的 url 中有个 #,例如 localhost:3000/#,HashRouter 通过 hash 值来对路由进行控制。如果你使用 HashRouter,你的路由就会默认有这个 #。

BrowserRouter 的 url 中没有 #,它的 url 如http://localhost:3001/user/login,BrowserRouter 的原理是依赖 HTML5 的 history API 实现的路由机制。

HashRouter 和 BrowserRouter 都具有 basename 属性,如果你的 URL 不是位于网站根目录,而是放在子目录里,你需要设置这个属性。如下:

<BrowserRouter basename="/calendar"/>
<Link to="/today"/> // 渲染为 <a href="/calendar/today">

Route#

Route 是 Router 的子元素,控制路径对应显示的组件。常用属性有 exact、path 以及 component。
考虑以下代码:

<Route path="/" exact component={HomePage} />
<Route path="/users" component={UsersPage} />

react-router4 的路由是包含性的,多个 Route 可以同时进行匹配和渲染,exact 控制到路径匹配成功时不会再继续向下匹配,在面代码中,我们试图根据路径渲染 HomePage 或者 UsersPage。如果从 Route 删除了 exact 属性,那么在浏览器中访问 /users 时,HomePage 和 UsersPage 组件将同时被渲染。

Switch#

在 Router 组件中的任意位置创建多个,但通常我们会把它们放在同一个位置。使用组件来包裹一组会遍历自身的子元素(即路由)并对第一个匹配当前路径的元素进行渲染。考虑如下代码:

<Switch>
  <Route exact path="/" component={DashBoard} />
  <Route path="/user" component={User} />
</Switch>

如果去掉 Switch 组件,当我们访问 /user 的时候,路由会同时匹配 “/” 和 /user,将同时渲染 DashBoard 和 User 组件。

react-router4 提供了两种导航 API,用于页面切换,当页面切换时,页面不会重新加载,但是组件会被重新渲染。它们作用相同,但 NavLink 在匹配 URL 成功时,可以提供一些额外的样式能力。

Link

Link 提供 to 属性控制跳转地址,可传入字符串或者对象。如下:

<Link to="/courses"/>to: object
<Link to={{
  pathname: '/courses',
  search: '?sort=name',
  hash: '#the-hash',
  state: { fromDashboard: true }
}}/>

NavLink

NavLink 可以给当前匹配成功的链接提供一个 className 类名,常在 Tab 导航中使用。

<nav>
  <NavLinkto="/app"exact activeClassName="active">Home</NavLink>
  <NavLinkto="/app/users"activeClassName="active">Users</NavLink>
  <NavLinkto="/app/products"activeClassName="active">Products</NavLink>
</nav>

路径参数#

在 react router4 中,match 用于获取路径上的参数,match 是使用渲染时传递到组件内的一个 props,在 react 组件内部通过 this.props.match 获取 match 的属性,
考虑如下代码:

<Switch>
  <Route exact path="/" component={DashBoard} />
  <Route path="/user/:id" component={User} />
  <Route path="/user" component={User} />
</Switch>

当访问http://localhost:3001/user/123 时,打印 this.props.match 的内容。
match 获取的属性主要有:
image

然后,通过 this.props.match.params.id 就可以获取路由匹配的 id 了。

withRouter#

试想,如果组件没有通过渲染,该如何获取 history、match、location 等 props 呢?react router4 提供了一个高阶组件 withRouter。使用方法如下:

import { withRouter } from 'react-router-dom';

使用 withRouter 有两种办法,第一种简洁的方法是使用装饰器,如下:

@withRouter
class AuthRoute extends React.Component {
}

另一种方法直接调用 withRouter 包裹原来的组件返回一个新的组件:

class Auth extends React.Component {

}
const AuthRoute = withRouter(Auth)

通过以上两种方法,就能在组件内部使用路由的 props 了。如下:

const { matchlocationhistory} = this.props;

结语#

关于 react router4, 本文只是讲解了一些常用的 api 和用法,需要学习的还有很多,这里只是开始。

参考#

react router 官方文档

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。