React-router-dom 是专门用于web应用的路由解决方案。
要想实现路由相关组件,我们需要借助一个库 history,这个库提供了一个方法 createBrowserHistory,可以用来创建一个 history 对象,保存路由历史记录等信息,也可以监听路由变化。
1. Link
Link 组件的 to 属性指定了点击该链接后会跳转的路由,Route 组件的 path 属性指定了该 Route 组件会匹配的路由,如果匹配上了就渲染 children , component , render 属性指定的组件(这三个属性都是用来指定待渲染组件的)
三者的优先级为 children > component > render
- Link 组件的实质就是一个 a 标签
- Link 组件的 to 属性就是 a 标签的 href 属性
- 点击 a 标签的默认行为会刷新页面,需要给 a 标签添加 onClick 方法,阻止默认行为
- 使用 history 对象的 push 方法(这里的 history 对象是通过 context 进行传递的),这就是为什么 Link、Route 等组件必须写在 Router 组件中的原因。
2. Router
Router 组件的 props 中有一个 history 对象,主要用来获取路由的 location 信息,以及监听路由的变化。同时 Router 组件还利用 Context 将 history、location 等路由信息传递给下层组件,所以我们需要创建一个 Context 对象
在 react-router-dom 中 Router 组件有几个不同的类型,例如:BrowserRouter 、HashRouter
3. Route
首先我们通过 props 获取 Route 组件上的一些属性 path, children, component, render ,然后从 context 中获取当前的 location 对象,里面保存着当前路由地址。
然后拿着 path 和当前 location 信息进行匹配,这里为了方便我们使用了 react-router-dom 提供的一个方法 matchPath 来进行路由匹配,并返回匹配信息, 获取到 match 对象后,说明匹配成功
然后就按照 children > component > render 的顺序,对组件进行渲染。
类组件和函数组件如何获取 history 对象(实现 Route 组件的时候,我们会将 context 对象传递给待渲染的组件,也就是 history,location,match 三个对象。)
- 类组件
(1)使用 withRouter 高阶组件将我们的组件进行包装
(2)源码:获取到 Context 对象,然后传递给入参组件 - 函数组件
(1)使用 useHistory,useLocation,useRouteMatch,useParams 这几个 hooks
(2)源码:使用 useContext 获取到 context 对象,再把里面的 history,location,match 等对象返回
4. Switch
将 Route 组件放在 Switch 组件中,就只会渲染第一个与路由地址匹配到的 Route 组件。
如果只是一堆 Route 组件,当路由地址为 /about 时,About、User、NoMatch 三个组件都将被渲染,
如果用 Switch 包裹,就只会渲染 About 组件。
- 源码:
- 对 Switch 的子组件进行遍历,找到第一个与当前路由地址匹配的组件,然后进行渲染。但是遍历结果有三种可能,无,一个,多个。
- 则React 就提供了这个方法来方便遍历子组件。找到第一个匹配的子组件后,使用 React.cloneElement 克隆一个该组件,并把匹配信息(即 matchPath 方法返回的 match 对象)传给该组件。
总结
1、Router 组件将 history 对象通过 Context 传递给下层的 Link 和 Route 组件;
2、点击 Link 组件触发 history 对象的更新;
3、Route 组件监听 history 对象的变化,拿到最新的路由信息和自身的 path 进行比较,如果匹配上就去渲染 component 或 render 属性指定的组件。
————————————————
记录大概知识点,详情见react-router-dom使用及源码实现

本文详细介绍了React Router DOM的核心组件Link、Route和Switch的使用,以及history对象在路由管理中的作用。Link组件用于创建导航链接,Route组件根据路径匹配并渲染组件,Switch确保只渲染第一个匹配的Route。history对象用于跟踪和管理路由变化,而Context机制使得这些组件能够共享路由信息。同时,文章提到了如何在类组件和函数组件中获取history对象,并强调了Router组件在传递路由信息方面的重要性。
1万+

被折叠的 条评论
为什么被折叠?



