前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版

React之React Router 4(十一)

首页2017-11-20 00:06:10Front-End
RouterReact

# 一、React-router V4版本修改内容及一些坑

1、所有组件更改为从react-router-dom导入

//v2
import {Router,Route,hashHistory} from 'react-router';

// 4.xx写法
//v4
import {Route,BrowserRouter as Router, Switch} from 'react-router-dom';

// 如果搭配redux,你还需要使用react-router-redux
@前端进阶之旅: 代码已经复制到剪贴板

2、将所有<Router>替换为<BrowserRouter>

//v2
 <Router history={hashHistory}>
  <Route path="/" component={PCIndex}></Route>
  <Route path="/details/:uniqueky" component={PCNewsDetails}></Route>
  <Route path="/usercenter" component={PCUserCenter}></Route>
 </Router>
@前端进阶之旅: 代码已经复制到剪贴板

现在需要更改为BrowserRouter

  • 这里的代码不仅仅是将Router替换为BrowserRouter,而且还把所有的Route中用Switch包裹起来.
//v4
<BrowserRouter>
  <Switch>
   <Route exact path="/" component={MobileIndex}></Route>
   <Route path="/details/:uniqueky" component={MobileNewsDetails}></Route>
   <Route path="/usercenter" component={MobileUserCenter}></Route>
  </Switch>
 </BrowserRouter>
@前端进阶之旅: 代码已经复制到剪贴板

3、<BrowserRouter>只能有一个子节点

<BroserRouter>只能有一个子节点,所以官网建议的是使用<Switch>进行包裹

// v3
<Route path='/' component={App}>
 <IndexRoute component={Home} />
 <Route path='about' component={About} />
 <Route path='contact' component={Contact} />
</Route>
@前端进阶之旅: 代码已经复制到剪贴板
// v4
const App = () => (
 <Switch>
  <Route exact path='/' component={Home} />
  <Route path='/about' component={About} />
  <Route path='/contact' component={Contact} />
 </Switch>
)
@前端进阶之旅: 代码已经复制到剪贴板

4、最坑的地方:在当前目录下的文件路径不再使用./, 而是直接用/.

在进行文件引用的时候 ,./src/js的写法需要更改文’/src/js’, 这是更改之后最坑的地方

# 二、安装

react-router-dom暴露出react-router中暴露的对象与方法,因此你只需要安装并引用react-router-dom即可

npm install --save react-router-dom
@前端进阶之旅: 代码已经复制到剪贴板

# 三、路由器(Router)

在你开始项目前,你需要决定你使用的路由器的类型。对于网页项目,存在<BrowserRouter>与<HashRouter>两种组件。当存在服务器来管理动态请求时,需要使用<BrowserRouter>组件,而<HashRouter>被用于静态网站。通常,我们更倾向选择<BrowserRouter>,但如果你的网站仅用来呈现静态文件,那么<HashRouter>将会是一个好选择

# 四、历史(History)

每个路由器都会创建一个history对象并用其保持追踪当前location[注1]并且在有变化时对网站进行重新渲染。这个history对象保证了React Router提供的其他组件的可用性,所以其他组件必须在router内部渲染。一个React Router组件如果向父级上追溯却找不到router组件,那么这个组件将无法正常工作

# 五、渲染<Router>

路由器组件无法接受两个及以上的子元素。基于这种限制的存在,创建一个<App>组件来渲染应用其余部分是一个有效的方法

import { BrowserRouter } from 'react-router-dom'
ReactDOM.render((
  <BrowserRouter>
    <App />
  </BrowserRouter>
), document.getElementById('root'))
@前端进阶之旅: 代码已经复制到剪贴板

# 六、<App>

应用通过<App>组件定义。简化一下,我们将应用拆分成两个部分。<Header>组件包含网站的导航链接。<Main>组件则呈现其余内容

const App = () => (
  <div>
    <Header />
    <Main />
  </div>
)
@前端进阶之旅: 代码已经复制到剪贴板

# 七、路由(Route)

<Route>组件是React Router中主要的结构单元。在任意位置只要匹配了URL的路径名(pathname)你就可以创建<Route>元素进行渲染

1、路径(Path)

<Route>接受一个数为string类型的path,该值路由匹配的路径名的类型。例如:<Route path='/roster'/>会匹配以/roster开头的路径名。在当前path参数与当前location的路径相匹配时,路由就会开始渲染React元素。若不匹配,路由不会进行任何操作

<Route path='/roster'/>
// 当路径名为'/'时, path不匹配
// 当路径名为'/roster'或'/roster/2'时, path匹配
// 当你只想匹配'/roster'时,你需要使用"exact"参数
// 则路由仅匹配'/roster'而不会匹配'/roster/2'
<Route exact path='/roster'/>
@前端进阶之旅: 代码已经复制到剪贴板
  • 注意:在匹配路由时,React Router只关注location的路径名。当URL如下时
http://www.example.com/my-projects/one?extra=false
@前端进阶之旅: 代码已经复制到剪贴板
  • React Router去匹配的只是'/my-projects/one'这一部分

2、匹配路径

path-to-regexp包用来决定route元素的path参数与当前location是否匹配。它将路径字符串编译成正则表达式,并与当前location的路径名进行匹配比较

  • 当路由地址匹配成功后,会创建一个含有以下属性的match对象:
    • url :与当前location路径名所匹配部分
    • path:路由的地址
    • isExact :path 是否等于 pathname
    • params:从path-to-regexp获取的路径中取出的值都被包含在这个对象中

使用 route tester这款工具来对路由与URL进行检验

3、创建你的路由

可以在路由器(router)组件中的任意位置创建多个<Route>,但通常我们会把它们放在同一个位置。使用<Switch>组件来包裹一组<Route>。<Switch>会遍历自身的子元素(即路由)并对第一个匹配当前路径的元素进行渲染

  • 我们希望匹配一下路径
    • /:主页
    • /roster: 团体列表
    • /roster/:number:运动员页面,使用运动员的编号作为标识
    • /schedule:团队的赛程表

为了在应用中能匹配路径,在创建<Route>元素时必须带有需要匹配的path作为参数

<Switch>
  <Route exact path='/' component={Home}/>
  {/* both /roster and /roster/:number begin with /roster */}
  <Route path='/roster' component={Roster}/>
  <Route path='/schedule' component={Schedule}/>
</Switch>
@前端进阶之旅: 代码已经复制到剪贴板

4、<Route>是如何渲染的?

当一个路由的path匹配成功后,路由用来确定渲染结果的参数有三种。只需要提供其中一个即可

  • component : 一个React组件。当带有component参数的route匹配成功后,route会返回一个新的元素,其为component参数所对应的React组件(使用React.createElement创建)。
  • render : 一个返回React element的函数。当匹配成功后调用该函数。该过程与传入component参数类似,并且对于行级渲染与需要向元素传入额外参数的操作会更有用。
  • children : 一个返回React element的函数。与上述两个参数不同,无论route是否匹配当前location,其都会被渲染
<Route path='/page' component={Page} />
const extraProps = { color: 'red' }
<Route path='/page' render={(props) => (
  <Page {...props} data={extraProps}/>
)}/>
<Route path='/page' children={(props) => (
  props.match
    ? <Page {...props}/>
    : <EmptyPage {...props}/>
)}/>
@前端进阶之旅: 代码已经复制到剪贴板

通常component参数与render参数被更经常地使用。children参数偶尔会被使用,它更常用在path无法匹配时呈现的’空’状态。在本例中并不会有额外的状态,所以我们将使用<Route>的component参数

  • 通过<Route>渲染的元素会被传入一些参数。分别是match对象,当前location对象以及history对象(由router创建)

5、<Main>

现在我们清楚了根路由的结构,我们需要实际渲染我们的路由。对于这个应用,我们将会在<Main>组件中渲染<Switch>与<Route>,这一过程会将route匹配生成的HTML放在<main>节点中

import { Switch, Route } from 'react-router-dom'
const Main = () => (
  <main>
    <Switch>
      <Route exact path='/' component={Home}/>
      <Route path='/roster' component={Roster}/>
      <Route path='/schedule' component={Schedule}/>
    </Switch>
  </main>
)
@前端进阶之旅: 代码已经复制到剪贴板
  • 注意:主页路由包含额外参数。该参数用来保证路由能准确匹配path

6、嵌套路由

fe
  • 一、React-router V4版本修改内容及一些坑
  • 二、安装
  • 三、路由器(Router)
  • 四、历史(History)
  • 五、渲染
  • 六、<App>
  • 七、路由(Route)
  • 八、inclusive routing
  • 九、Exclusive Routing
  • 十、Index Routes" 和 “Not Found”
  • 十一、Link
  • 十二、Match
  • 十三、Authorized Route
  • 十四、<Link>
  • 十五、<Switch>
  • 十六、更多参考

← React之Immutable学习记录(十二)Redux之react结合redux实战篇(十) →