深入理解react-router 路由的实现原理
react router 是一个基于 react 之上的强大路由库,它可以让你向应用中快速地添加视图和数据流,同时保持页面与 url 间的同步。本文从两个方便来解析 react-router 实现原理。一:介绍 react-router 的依赖库history;二:使用 history 库,实现一个简单的 react-router 路由。
history 介绍
history 是一个 javascript 库,可让您在 javascript 运行的任何地方轻松管理会话历史记录。history 抽象出各种环境中的差异,并提供最小的 api ,使您可以管理历史堆栈,导航,确认导航以及在会话之间保持状态。
history 有三种实现方式:
1、browserhistory:用于支持 html5 历史记录 api 的现代 web 浏览器(请参阅跨浏览器兼容性)
2、hashhistory:用于旧版web浏览器
3、memoryhistory:用作参考实现,也可用于非 dom 环境,如 react native 或测试
三种实现方法,都是创建了一个 history 对象,这里主要讲下前面两种:
const history = { length: globalhistory.length, action: "pop", location: initiallocation, createhref, push, // 改变location replace, go, goback, goforward, block, listen //监听路由变化 };
1.页面跳转实现
browserhistory:pushstate、replacestate;
hashhistory:location.hash、location.replace
function push(){ createkey(); // 创建location的key,用于唯一标示该location,是随机生成的 if(browserhistory){ globalhistory.pushstate({ key, state }, null, href); }else if(hashhistory){ window.location.hash = path; } //上报listener 更新state ... } function replace(){ createkey(); // 创建location的key,用于唯一标示该location,是随机生成的 if(browserhistory){ globalhistory.replacestate({ key, state }, null, href); }else if(hashhistory){ window.location.replace(window.location.href.slice(0, hashindex >= 0 ? hashindex : 0) + "#" path); } //上报listener 更新state ... }
2.浏览器回退
browserhistory:popstate;
hashhistory:hashchang;
if(browserhistory){ window.addeventlistener("popstate", routerchange); }else if(hashhistory){ window.addeventlistener("hashchange", routerchange); } function routerchange(){ const location = getdomlocation(); //获取location //路由切换 transitionmanager.confirmtransitionto(location,callback=()=>{ //上报listener transitionmanager.notifylisteners(); }); }
通过 history 实现简单 react-router
import { component } from 'react'; import createhistory from 'history/createhashhistory'; const history = createhistory(); //创建 history 对象 /** * 配置路由表 * @type {{"/": string}} */ const router = { '/': 'page/home/index', '/my': 'page/my/index' } export default class router extends component { state = { page: null } async route(location) { let pathname = location.pathname; let pagepath = router[pathname]; // 加 ./的原因 https://webpack.docschina.org/api/module-methods#import- const page = await import(`./${pagepath}`); //获取路由对应的ui //设置ui this.setstate({ page: page.default }); } initlistener(){ //监听路由切换 history.listen((location, action) => { //切换路由后,更新ui this.route(location); }); } componentdidmount() { this.route(history.location); this.initlistener(); } render() { const { page } = this.state; return page && <page {...this.props} />; } }
目前react-router在项目中已有大量实践,其优点可以总结如下:
风格: 与react融为一体,专为react量身打造,编码风格与react保持一致,例如路由的配置可以通过component来实现
简单: 不需要手工维护路由state,使代码变得简单
强大: 强大的路由管理机制,体现在如下方面
- 路由配置: 可以通过组件、配置对象来进行路由的配置
- 路由切换: 可以通过<link> redirect进行路由的切换
- 路由加载: 可以同步记载,也可以异步加载,这样就可以实现按需加载
使用方式: 不仅可以在浏览器端的使用,而且可以在服务器端的使用
当然react-router的缺点就是api不太稳定,在升级版本的时候需要进行代码变动。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。