利用context hashchange 实现router
大致思路如下
- 利用context保证唯一路由信息,以及传递路由信息
- 监听hashchange 修改当前路由信息
ps 以下代码都是基于hooks,而且只实现了HashRouter,如果要实现BrowserRouter就要监听popstate事件
//HashRouter.js
import React, { useState, useEffect } from 'react';
import Context from "./context";
const HashRouter = (props) => {
const [location,setLocation]=useState({
pathname: window.location.hash.slice(1) || "/", // 获取浏览器地址栏中的hash值,如果不存在则默认为"/"
query: undefined
})
useEffect(()=>{
window.addEventListener("hashchange", () => { // 监听浏览器地址栏hash值变化
setLocation(
{
...location,
pathname: window.location.hash.slice(1) // 更新pathname
}
)
});
},[])
const currentRoute = {
location: location,
history: { // 新增一个history对象用于实现当前路由的切换
push: (to) => {
if (typeof to === "object") { // 如果to是一个对象
let { pathname, query } = to; // 取出pathname和query
window.location.hash = pathname; // 更新浏览器hash值,触发浏览器hashchange事件
location.query = query; // 更新query
} else { // 修改浏览器地址栏的hash值
window.location.hash = to; // 更新浏览器hash值
}
}
}
}
return (
<Context.Provider value={currentRoute}>
{props.children}
</Context.Provider>
);
};
export default HashRouter;
//Route.js
import React, {useContext} from "react";
import Context from "./context";
const Route = (props) => {
const context=useContext(Context)
const currentRoutePath = context.location.pathname; // 从上下文中获取到当前路由的路径
const {path, component:Component} = props; // 获取给Route组件传递的props属性
const props2 = {
...context
}
if (currentRoutePath === path) {
return (
<Component {...props2}></Component>
);
}
return null
};
export default Route;
完整代码地址:https://github.com/dz333333/toy–router
参考:https://segmentfault.com/a/1190000022250917