学习源码最好的方式是模仿着自己写一个,所以今天我们来实现一个简单的 react-router。
Router
我们先来实现一下 Router:
1 | class Router extends Component { |
Router 很简单,就是通过 context 把路由相关信息传递下去,同时监听 history 的变化。
1 | class BrowserRouter extends Component { |
BrowserRouter 是建立在 Router 基础之上的,只是传入了一个适配浏览器平台的 history。
Route
1 | export default class Route extends Component { |
Route 其实也挺简单的,拿到 context 中的当前 location 与 props 中的 path 进行一个匹配,然后按照 children, component 和 render 的顺序来渲染组件。如果没传 path,比如说 404 页面,则用 context.match 作为最终匹配的 match。
这里注意需要覆盖掉 Router 中传过来的 match,然后继续传给下面的组件。
Switch
1 | class Switch extends Component { |
Switch 的作用就是找到第一个匹配的 Route 进行渲染,其他的则忽略。所以这里需要对 Switch 中的所有子组件进行一个遍历。注意到如果 Switch 下如果有非 Router 的组件,按照这里的逻辑 match 会是 context.match,所以最后会被渲染出来。
其他
主要的组件都写出来了,其他一些边界料的工作也比较简单了。
Link
1 | class Link extends Component { |
hooks
1 | export function useHistory() { |
Prompt
1 | function Prompt({when = true, message}) { |