window.addEventListener("hashchange", () => {});
function push(path) {
history.pushState({
title: "",
path: path
});
}
window.addEventListener("popstate", e => {
console.log(e);
});
function app() {
return (
<div>
<div>
<Link to="/home" />
</div>
<Router>
<Switch>
<Route path="" component={} />
</Switch>
</Router>
</div>
);
}
const {Provider, Consumer} = React.createContext();
// 手写
const HashRouter = (props) => {
const {path, component, children} = props;
const router = {
location: {
pathname: window.location.hash.slice(1) || ""
},
history: {
push(to){
window.location.hash = to;
}
},
match: {
params: {}
}
};
window.addEventListener("hashchange", ()=>{
// 修改路由
});
window.location.hash = window.location.hash || "/";
return (
<Provider value={router}>
{children}
</Provider>
);
}
const Route = (props) => {
const {path, Component, exact= false} = props;
return (
<Consumer>
{router => {
const {location} = router;
// 通过正则匹配,可用path-to-regexp插件
if(path === location.pathname){
return <Component {...props}/>
}
return null;
}}
</Consumer>
);
}
const Link = (props) => {
const {to} = props;
return (
<Consumer>
{state => {
return <a onClick={()=>{
state.history.push(to);
}} >
{this.props.children}
</a>
}}
</Consumer>
);
}
const Redirect = (props) => {
const {to} = props;
return (
<Consumer>
{state => {
state.history.push(to);
return null;
}}
</Consumer>
);
}
// 匹配一个Route
const Switch = (props) => {
const {children} = props;
return (
<Consumer>
{state => {
const pathname = state.location.pathname;
children.forEach(item => {
// regex 为 item.props.path 的正则表达式
if(regex.test(pathname)){
return item;
}
});
return null;
}}
</Consumer>
);
}