react后台管理系统路由方案及react-router原理解析
最近做了一个后台管理系统主体框架是基于React进行开发的,因此系统的路由管理,选用了react-router(4.3.1)插件进行路由页面的管理配置。
实现原理剖析
1、hash的方式
以 hash 形式(也可以使用 History API 来处理)为例,当 url 的 hash 发生变化时,触发 hashchange 注册的回调,回调中去进行不同的操作,进行不同的内容的展示
function Router() {undefined
this.routes = {};
this.currentUrl = ‘’;
}
Router.prototype.route = function(path, callback) {undefined
this.routes[path] = callback || function(){};
};
Router.prototype.refresh = function() {undefined
this.currentUrl = location.hash.slice(1) || ‘/’;
this.routesthis.currentUrl;
};
Router.prototype.init = function() {undefined
window.addEventListener(‘load’, this.refresh.bind(this), false);
window.addEventListener(‘hashchange’, this.refresh.bind(this), false);
}
window.Router = new Router();
window.Router.init();
我们也可以自己进行模拟,可以写成这样:
function App() {undefined
// 进入页面时,先初始化当前 url 对应的组件名
let hash = window.location.hash
let initUI = hash === ‘#login’ ? ‘login’ : ‘register’
let [UI, setUI] = useState(initUI);
let onClickLogin = () => {undefined
setUI(‘Login’)
window.location.hash = ‘login’
}
let onClickRegister = () => {undefined
setUI(‘Register’)
window.location.hash = ‘register’
}
let showUI = () => {undefined
switch(UI) {undefined
case ‘Login’:
return
case ‘Register’:
return
}
}
return (
Login
Register
{showUI()}
);
}
这样其实已经满足我们的要求了,如果我在地址栏里输入 localhost:8080/#login,就会显示 。但是这个 “#” 符号不太好看,如果输入 localhost:8080/login 就完美了。
2、history的方式
H5 提供了一个好用的 history API,使用 window.history.pushState() 使得我们即可以修改 url 也可以不刷新页面,一举两得。现在只需要修改点击回调里的 window.location.pathname = ‘xxx’ 就可以了,用 window.history.pushState() 去代替。
function App() {undefined
// 进入页面时,先初始化当前 url 对应的组件名
let pathname = window.location.pathname
let initUI = pathname === ‘/login’ ? ‘login’ : ‘register’
let [UI, setUI] = useState(initUI);
let onClickLogin = () => {undefined
setUI(‘Login’)
window.history.pushState(null, ‘’, ‘/login’)
}
let onClickRegister = () => {undefined
setUI(‘Register’)
window.history.pushState(null, ‘’, ‘/register’)
}
let showUI = () => {undefined
switch(UI) {undefined
case ‘Login’:
return
case ‘Register’:
return
}
}
return (
Login
Register
{showUI()}
);
}
3、link的实现
react-router依赖基础—history,history是一个独立的第三方js库,可以用来兼容在不同浏览器、不同环境下对历史记录的管理,拥有统一的API。具体来说里面的history分为三类:
老浏览器的history: 主要通过hash来实现,对应createHashHistory,通过hash来存储在不同状态下的history信息
高版本浏览器: 通过html5里面的history,对应createBrowserHistory,利用HTML5里面的history
node环境下: 主要存储在memeory里面,对应createMemoryHistory,在内存中进行历史记录的存储
执行URL前进
createBrowserHistory: pushState、replaceState
createHashHistory: location.hash=*** location.replace()
createMemoryHistory: 在内存中进行历史记录的存储
执行URL回退
createBrowserHistory: popstate
createHashHistory: hashchange
React组件为什么会更新
其实无论是react-router. react-redux. 能够使组件更新的根本原因,还是最后出发了setState函数;对于react-router,其实是对history原生对象的封装,重新封装了push函数,使得我们在push函数执行的时候,可以触发在Router组件中组件装载之前,执行了history.listener函数,该函数的主要作用就是给listeners数组添加监听函数,每次执行history.push的时候,都会执行listenrs数组中添加的listener, 这里的listener就是传入的箭头函数,功能是执行了Router组件的setState函数,Router执行了setState之后,会将当前url地址栏对应的url传递下去,当Route组件匹配到该地址栏的时候,就会渲染该组件,如果匹配不到,Route组件就返回null;
componentWillMount() {undefined
const { children, history } = this.props
更多内容请见原文,文章转载自:https://blog.csdn.net/weixin_44519496/article/details/118522634