学习源码最好的方式是模仿着自己写一个,所以今天我们来实现一个简单的 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}) { |