react-router-dom源码分析

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

React-router-dom 是专门用于web应用的路由解决方案。

要想实现路由相关组件,我们需要借助一个库 history,这个库提供了一个方法 createBrowserHistory,可以用来创建一个 history 对象,保存路由历史记录等信息,也可以监听路由变化。

1. Link

Link 组件的 to 属性指定了点击该链接后会跳转的路由,Route 组件的 path 属性指定了该 Route 组件会匹配的路由,如果匹配上了就渲染 children , component , render 属性指定的组件(这三个属性都是用来指定待渲染组件的)

三者的优先级为 children > component > render

  1. Link 组件的实质就是一个 a 标签
  2. Link 组件的 to 属性就是 a 标签的 href 属性
  3. 点击 a 标签的默认行为会刷新页面,需要给 a 标签添加 onClick 方法,阻止默认行为
  4. 使用 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使用及源码实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值