history
react router 基于 history 库实现,history 有统一的 api 兼容不同浏览器、不同环境下的历史记录管理,history 包含三种模式:
- hash,低版本浏览器
- browser,高版本浏览器,利用 html5 的 history
- pushhistory 和 replacehistory 不会触发 popstate,back 和 forword 会触发
- 不兼容低版本浏览器,需要后端匹配url,否则世界访问会 404
- memory,node环境下,存储在 memory中
对应三大方法的实现:
createHashHistory
url 前进
- window.location.hash = path;
window.location.replace(window.location.pathname + window.location.search + '#' + path);
url 后退
- addEventListener(window, ‘hashchange’, hashChangeListener);
createBrowserHistory
url 前进
- window.history.pushState
- window.history.replaceState
url 后退
- addEventListener(window, ‘popstate’, popStateListener);
createMemoryHistory
react-router 原理梳理
react-router 的核心组件包括 Route 、MemoryRouter (不涉及 dom 在 react-router 中定义),Router、Link、BrowserRouter、HistoryRouter(涉及到 dom 在 react-dom 中定义)
还有两个 context 组件 RouterContext 、HistoryContext 用于在组件中传递 router 和 history 相关的 props。
还有个 createNameContext 用于创建有displayName的context
react-
router 基本原理如下:
Route、Router、Link 三个组件即可构成一个基本 react-router应用
Router 组件
使用 route 时,在 route 之外会用 browserRouter HistoryRouter 包起来,他们是基于 router 组件实现的。
BrowserRouter、HistoryRouter、MemoryRouter 本质都是调用 Router 组件。
router 组件 调用 history 的 listen 监听 url 变化, 比较 url 是否 rootmatch 从而更新下级组件的 match 状态 props:
Link 组件
类似 a 标签,用于主动触发改变 url 的方法 。从 context 中拿到 history ,再根据 Props 有没有 replace 去执行 history.replace 和 history.push
Route 组件
用于在 url 改变时判断如何更新视图:自身有props path,通过比较 path 和 url 。
比较的时候会做缓存,缓存上限 10000。
匹配成功则渲染 component props 、render props、 children props,排序即优先级: