# react-router
## Router
核心在于实现URL与path相同时的组件渲染。使用matchPath方法进行检测。
~~~
const matchPath = (pathname, options) => {
const { exact = false, path } = options
if (!path) {
return {
path: null,
url: pathname,
isExact: true,
}
}
const match = new RegExp(`^${path}`).exec(pathname)
if (!match) {
// There wasn't a match.
return null
}
const url = match[0]
const isExact = pathname === url
if (exact && !isExact) {
// There was a match, but it wasn't
// an exact match as specified by
// the exact prop.
return null
}
return {
path,
url,
isExact,
}
}
~~~
> 首先进行空检测,当发现 path 为未定义或者为空时则直接返回匹配成功(组件不指定path则默认渲染)。接下来使用正则检测传入的 path 与当前的 location.pathname 是否匹配,不匹配则返回 null。如果匹配成功还要检测下是否是完全匹配,即全等。如果不是完全匹配,却传入了 exact 为 true 的选项,匹配依然失败返回null,其余情况匹配成功。
最后,如果传入了一个组件或者render函数,则分别调用 React.createElement 及 render 函数将其渲染,并传入 props。实际情况传入的 props 有很多,这里做了简化。
## Link
~~~
<Link to='/some-path' replace={false} />
~~~
to 是一个指向跳转目标地址的字符串,而 replace 则是布尔变量来指定当用户点击跳转时是替换 history 栈中的记录还是插入新的记录。Link 组件的渲染函数中需要返回一个锚标签,不过我们的前提是要避免每次用户切换路由的时候都进行整页的刷新,因此我们需要为每个锚标签添加一个点击事件的处理器:我们要禁止 a 标签的跳转行为。在使用 browserHistory 的情况下此时我们本质上会使用 HTML5 中的 pushState 与 replaceState 函数,这里进行了简单包装。
## 渲染
最后,我们需要考虑如何保证用户点击了 Link 组件之后触发全部路由组件的检测与重渲染。在我们上面实现的 Link 组件中,用户执行跳转之后浏览器的显示地址会发生变化,但是页面尚不能重新渲染;我们声明的 Route 组件并不能收到相应的通知。我们需要追踪那些显现在界面上实际被渲染的 Route 组件并且当路由变化时调用它们的 forceUpdate 方法。
Router 主要通过有机组合 setState、context 以及 history.listen 方法来实现该功能。每个 Route 组件被挂载时我们会将其加入到一个数组中,然后当 path 变化时,我们可以遍历该数组然后对每个实例调用 forceUpdate 方法:
- html
- 冒泡/捕获/委托
- 前端路由
- Dom
- 创建节点API
- 页面修改型API
- 节点查询型API
- 节点关系型API
- 元素属性API
- DOM事件
- classList
- 性能优化
- 节流防抖
- localStorage sessionStorage
- BOM
- meta
- data属性
- js实现拖拽
- html5
- 关于meta
- 轮播图
- js实现拖放
- 电话号inputFormater
- js
- es6
- promise
- iterator
- generator
- async
- proxy
- Set
- Map
- Object的扩展
- String
- Iterator
- Symbol
- 解构赋值
- 函数式编程
- module
- 基本数据类型
- 数组相关codings
- for of/for in
- this
- call bind apply
- 闭包
- 作用域
- prototype与继承
- 深浅拷贝
- setTimeOut/setInterval
- 垃圾处理机制
- 设计模式
- 观察者模式
- 单例模式
- 策略模式
- RegExp
- with
- 其他玩意
- Error/Stack Trace
- 面向对象
- css
- 回流重绘
- %取值
- 属性继承/属性优先级
- flex
- BFC
- 盒模型
- 设置css的方法
- 定位机制
- 块级/行内元素
- hack和一些别的玩意
- css动画
- 几个布局
- 画图形
- css3
- animation对比transform
- 点击不同图片区域跳转不同
- css选择器性能问题
- vh rem em
- css选择器
- 伪类伪元素
- css匹配原理
- 数据结构与算法
- 数据结构
- 树
- 链表
- 栈和队列
- 排序
- 归并排序
- 插入排序
- 选择排序
- 冒泡排序
- 快速排序
- 递归
- 回溯法
- 搜索算法
- 动态规划
- http
- 跨域问题
- CORS
- GET/POST
- ajax
- ajax上传文件
- http缓存
- https
- TCP/UDP
- cookie/session
- http2.0
- spdy
- websocket
- React
- redux
- 生命周期
- 虚拟dom与diff
- 双向数据绑定
- mvvm
- setState
- contextApi props reudx
- 高阶组件
- react-redux
- Fiber
- react-router
- 受控/非受控组件
- 待整理
- webpack
- loader实现
- 前端安全
- 移动端适配
- Vue
- 传值
- 其他