上一篇文章学习了Route
组件的实现机理, 而体系中的Switch
组件, 与Route
密切相关, 所以, 今天来咀嚼一下它.
一、更新
[2019-4-21]
Changed
- 改进文章排版格式
二、前言
PS: 无尽的知识, 能让一个沉默的人变得兴奋
一句话开头, 希望能带着这种劲头, 开始今天的Switch
的学习…
三、细说
3.1 前置知识
经过上一次的Route
的源码学习, 我们学习到了Route
组件的设计思路, 即:
Route
的作用主要是计算match
, 根据match
和决定渲染component
, 那么这篇文章学的Switch
, 则是:
PS: 计算match, 将计算之后的
computedMatch
传递给Route
Route
组件接收到computedMatch
之后, 不再去计算match
, 而是直接进行render
. 这也印证了Switch
这个名称, 即为切换
.
一句话概括:
PS:
Switch
的子组件Route
只能有一个被渲染出来
3.2 分割线
中间隔了五天, 由于在Gayhub
上看到了一个vscode
的issue
, 关于在工作区查找文件
的, 所以有感而发, 花了几天时间写了一个vscode
插件 —— File Positioning
, 昨天下午成功发布🐓🐓🐓
3.3 源码分析
废话少说, 还是接着上次的进度. 打开react-router/modules/Switch.js
, 可以看到, Switch
的源码非常简洁, 好像也并没有什么难的,
保持这种轻敌
的心态, 一步步来分析:
首先, 可以看到:
1 | return ( |
Switch
同样作为一个Consumer
- 消费者
, 接收到RouterContext
组件.
接着:
1 | const location = this.props.location || context.location; |
可以看到, 和Route
中一样, Switch
做了同样的操作 —— 计算location
, 这些都不是重点, 重点在下面这段代码:
1 | let element, match; |
为了更深的理解, 我将注释直接写在源码内
, 大致是这样的:
1 | // ** 定义两个变量, 分别存储`子组件`和`match对象` ** |
可以清楚的看到, Switch
内部同样是做了matchPath
的操作, 目的就是为了渲染出单一children, 同时, 印证了我们在开发的时候, 使用Switch
作路由截取
.
再往下看, 好像已经没内容了? 没错, 太简单了, 下面就开始实践环节.
四、实践
PS: 好记性不如烂笔头
分析完了源码之后, 接着完善自己的yyg-react-router-dom
库.
First and foremost
—— 首先也是最重要的一步, 就是定义Switch
所需的props
, 也就是约束interface
.
打开react-router官网, 可以看到, Switch
接收了两个props
, 分别是location
和children
, 🆗, 来书写interface
.
1 | // src/yyg-react-router-dom/components/Switch.tsx |
定义完成interface
, 回忆一下Route
组件中, 将context
处理分发到了handleProcess
函数中, 然后再handleProcess函数中, 分两步计算location
和依赖于location
的computeRoute
, 照猫画虎, 在render
中:
1 | // src/yyg-react-router-dom/components/Switch.tsx |
然后, 在computeLocation
和computeRoute
中, 分别进行相关的操作, 具体的代码下面会给出…
注意点: 在计算match
的过程中, 再此用到了matchPath
这个方法, 所以这里要将matchPath
提取出来, 以便复用.
因此, 在utils/utils.tsx
中新建工具组件, 主题内容不变, 只是将两个match
处理函数抽离出来, 并且改一下参数即可:
1 | // src/yyg-react-router-dom/utils/utils.tsx |
五、测试
写完之后, 再来做一下测试. 为了看到更直观的效果, 可以多创建一个Four.tsx
:
1 | // src/test/Four.tsx |
然后, 在App.tsx
中, 引入Switch.tsx
和Four.tsx
组件, 在render中新增测试代码:
1 | return ( |
打开浏览器, 可以看到, 此时此刻是空白的, 因为我们现在处于根url下, 分别在url栏中输入上面三个测试地址:
上面的gif, 可以清楚看到是正常渲染的, 进而证明我们自己的思路是正确的.
六、源码
源码地址: 点我
七、总结
PS: 一张思维脑图结束今天的学习