Open jingzhiMo opened 4 years ago
最近在看一下react-router的源码,看到react-rouer的功能分散到几个packages,也依赖基础包hisotry,如果完整源码分析,可能会有点多,所以这次就弄一个张图来说明一下react-router的使用。估计再过一阵子,v6版本就要发了,这个图是v5.x版本的,有点悲催。下面直接上图,主要说是在浏览器端运行的react-router:
react-router
react-rouer
packages
hisotry
v6
v5.x
图有点点长,先来简单说一下不同颜色的区域表示什么:
左边纵向的一列: react-router,react-router-dom,history表示不同的库,而window就是浏览器。
react-router-dom
history
window
下面就从对底层说起,捋一下这张图。
通常来说,路由库大部分基于两种:
一种是window.history对象来控制url的改变
window.history
另外一种是通过location.hash值来控制url的改变;
location.hash
现在应该大部分都是用window.history,如果要兼容部分低版本浏览器,可能就需要到location.hash。而这两者都需要到location的支持,才能获取更详细的信息。
location
需要注意的是,这是一个库,并不是window.history的对象。
这个库是对页面路径的操作进行封装,目前是独立一个仓库,github 地址,支持上面所说的window.history与location.hash的两种路由情况;
分别对应BrowserHistory与HashHistory的创建函数,通过这两个创建函数创建出来的对象,都具有相同的API调用,因为history这个库对这两种情况的路由进行了适配。通常这些通用的方法包含:
BrowserHistory
HashHistory
history.push() history.replace() history.go() history.back() // ... 等等 除此之外,还有定义一些路由过度的`promot`的逻辑等。
除此之外,还有还封装了MemoryHistory的创建方法,看起来,是给到react-router-native与部分测试的时候使用的。
MemoryHistory
react-router-native
这个是react-router的仓库其中一个package,是专门针对浏览器处理的路由封装。
通常我们是在这个库里面指定使用哪一种路由方式,BrowserHistory or hashHistory:
hashHistory
import { BrowserRouter as Router } from 'react-router-dom' // or import { HashRouter as Router } from 'react-router-dom'
而指定路由方式的时候,则调用hisotry的两种不同createHistory方法;获取创建的hisotry返回对象。
createHistory
react-router-dom处理指定路由方式之外,还提供Link与NavLink的组件;通常来说;这两个组件用于跳转到不同的路由,这个时候跳转也是调用createHistory返回对象的API,push或者replace
Link
NavLink
push
replace
react-router通常是开发者直接调用的入口,例如路由组件的分发,当前参数获取等。
我们知道,从react-router-dom引入BrowserRouter或者HashRouter来指定路由方式;其实这个时候,也返回一个Router的组件,用于渲染页面路由的根组件。
BrowserRouter
HashRouter
Router
Router的根组件是后面所有组件的基础;后续所有组件,必须在这个根组件下。Router,Switch等组件层层嵌套。在这个过程中,RouterContext是在整个组件过程中存在,这个context就是用于不同组件间的数据共享;通常这个context的数据为:
Switch
RouterContext
context
{ history, // createHistory 返回的对象 location, // 当前路径的信息 match // 当前路由匹配的信息 }
嵌套路由之间也是共用这个context,从而达到路由数据之间的传递;而hooks的调用也是基于useContext来演变成不同的hooks,例如useHistory,useLocation等。
hooks
useContext
useHistory
useLocation
那react-router-dom的Link更改的路由,怎么通知到context更改呢?
在createHistory的时候,返回的history对象️监听方法listen;而根组件Router监听该方法,若发生改变,则更改RouterContext的内容;从而做到不同组件间的数据通信。
listen
这篇文章对代码描述的不多,主要是对流程的处理进行梳理;了解到不同库之间的协作,与数据通信的技巧。具体实现还是得看源码。希望能够一图胜千言!!!喜欢给个star~
前言
最近在看一下
react-router
的源码,看到react-rouer
的功能分散到几个packages
,也依赖基础包hisotry
,如果完整源码分析,可能会有点多,所以这次就弄一个张图来说明一下react-router
的使用。估计再过一阵子,v6
版本就要发了,这个图是v5.x
版本的,有点悲催。下面直接上图,主要说是在浏览器端运行的react-router
:图有点点长,先来简单说一下不同颜色的区域表示什么:
左边纵向的一列:
react-router
,react-router-dom
,history
表示不同的库,而window
就是浏览器。下面就从对底层说起,捋一下这张图。
window
通常来说,路由库大部分基于两种:
一种是
window.history
对象来控制url的改变另外一种是通过
location.hash
值来控制url的改变;现在应该大部分都是用
window.history
,如果要兼容部分低版本浏览器,可能就需要到location.hash
。而这两者都需要到location
的支持,才能获取更详细的信息。history
需要注意的是,这是一个库,并不是
window.history
的对象。这个库是对页面路径的操作进行封装,目前是独立一个仓库,github 地址,支持上面所说的
window.history
与location.hash
的两种路由情况;分别对应
BrowserHistory
与HashHistory
的创建函数,通过这两个创建函数创建出来的对象,都具有相同的API调用,因为history
这个库对这两种情况的路由进行了适配。通常这些通用的方法包含:除此之外,还有还封装了
MemoryHistory
的创建方法,看起来,是给到react-router-native
与部分测试的时候使用的。react-router-dom
这个是
react-router
的仓库其中一个package,是专门针对浏览器处理的路由封装。通常我们是在这个库里面指定使用哪一种路由方式,
BrowserHistory
orhashHistory
:而指定路由方式的时候,则调用
hisotry
的两种不同createHistory
方法;获取创建的hisotry
返回对象。react-router-dom
处理指定路由方式之外,还提供Link
与NavLink
的组件;通常来说;这两个组件用于跳转到不同的路由,这个时候跳转也是调用createHistory
返回对象的API,push
或者replace
react-router
react-router
通常是开发者直接调用的入口,例如路由组件的分发,当前参数获取等。我们知道,从
react-router-dom
引入BrowserRouter
或者HashRouter
来指定路由方式;其实这个时候,也返回一个Router
的组件,用于渲染页面路由的根组件。Router
的根组件是后面所有组件的基础;后续所有组件,必须在这个根组件下。Router
,Switch
等组件层层嵌套。在这个过程中,RouterContext
是在整个组件过程中存在,这个context
就是用于不同组件间的数据共享;通常这个context
的数据为:嵌套路由之间也是共用这个
context
,从而达到路由数据之间的传递;而hooks
的调用也是基于useContext
来演变成不同的hooks
,例如useHistory
,useLocation
等。那
react-router-dom
的Link
更改的路由,怎么通知到context
更改呢?在
createHistory
的时候,返回的history
对象️监听方法listen
;而根组件Router
监听该方法,若发生改变,则更改RouterContext
的内容;从而做到不同组件间的数据通信。小结
这篇文章对代码描述的不多,主要是对流程的处理进行梳理;了解到不同库之间的协作,与数据通信的技巧。具体实现还是得看源码。希望能够一图胜千言!!!喜欢给个star~