上一篇文章学习了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: 一张思维脑图结束今天的学习
