history是react-router-dom里面的
src/pages/MyRouterPage.js
import React, { Component } from "react";
// import { BrowserRouter, Link, Route } from "react-router-dom";
import { BrowserRouter, Link, Route } from "../my-react-router-dom";
import HomePage from "./HomePage";
import UserPage from "./UserPage";
export default class MyRouterPage extends Component {
render() {
return (
<div>
<h3>MyRouterPage</h3>
<BrowserRouter>
<Link to="/">首页</Link>
<Link to="/user">用户中心</Link>
<Route path="/" exact component={HomePage} />
<Route path="/user" component={UserPage} />
</BrowserRouter>
</div>
);
}
}
my-react-router-dom.js
import React, { Component, useContext } from "react";
import { createBrowserHistory } from "history";
const RouterContext = React.createContext();
export class BrowserRouter extends Component {
constructor(props) {
super(props);
//获取history history是解决了a标签禁止浏览器跳转事件之后 链接不跳转的问题 其实就是跳转链接而页面不跳动
this.history = createBrowserHistory();
//把history作为参数
this.state = {
location: this.history.location,
};
//监听history变化
this.unlisten = this.history.listen(location => {
this.setState({ location });
});
console.log("this", this.history);
}
//移除监听
componentWillUnmount() {
if (this.unlisten) {
this.unlisten();
}
}
render() {
//获取节点 直接显示
const { children } = this.props;
return (
// context传出参数
<RouterContext.Provider
value={{
history: this.history,
location: this.state.location,
}}
>
{children}
</RouterContext.Provider>
);
}
}
export function Route(props) {
//拿到传进来的path和组件
const { path, component: Cmp } = props;
//useContext用来拿Provider传出的参数
const ctx = useContext(RouterContext);
//拿到location
const { location } = ctx;
//如果本页面路径跟跳转路径一致就显示
const match = path === location.pathname;
return match && <Cmp />;
}
export class Link extends Component {
//拿到location.history push到对应路径
handleClick = (event, history) => {
const { to } = this.props;
event.preventDefault();
history.push(to);
};
render() {
const { children, to } = this.props;
return (
// Consumer 拿到location 传给点击事件 href就是跳转的路径
<RouterContext.Consumer>
{ctx => {
return (
<a
href={to}
onClick={event => this.handleClick(event, ctx.history)}
>
{children}
</a>
);
}}
</RouterContext.Consumer>
);
}
}