调用界面
import React, {Component} from 'react';
// import {BrowserRouter, Link, Route, Switch} from "react-router-dom";
import {BrowserRouter, Link, Route} from "../../myReactRoute"; // 引入自己定义的文件
import UserPage from "./userPage";
import Home from "./Home";
class RouteCom extends Component {
render() {
return (
<div>
<h1>routeCom</h1>
<BrowserRouter>
<Link to={'/'}>首页</Link>
<Link to={'/user'}>用户中心</Link>
<Link to={'/404'}>404</Link>
<Route exact path={'/'} component={Home}></Route>
<Route path={'/user'} component={UserPage}></Route>
<Route component={() => <h1>404</h1>} />
</BrowserRouter>
</div>
);
}
}
export default RouteCom;
自定义实现界面
import React, {Component, useContext} from 'react';
import {createBrowserHistory} from 'history' // 该包可以获取当前路径信息
const RouteContext = React.createContext() // 创建context传值
const RouteProvider = RouteContext.Provider
const RouteConsumer = RouteContext.Consumer
export class BrowserRouter extends Component {
constructor(props) {
super(props);
this.history = createBrowserHistory()
console.log(this.history)
this.state = {
location: this.history.location //将路径信息值传递给state以便进行双向绑定
}
this.unlisten = this.history.listen((location) => {
this.setState({
location
})
})
// console.log(this.history)
}
componentWillUnmount() {
this.unlisten && this.unlisten() // 退出销毁监听
}
render() {
const {children} = this.props
const {location} = this.state
return (
// 将路径信息值传递
<RouteProvider value={{history: this.history, location: location}}>
{children}
</RouteProvider>
);
}
}
export class Link extends Component { // link的本质还是一个a标签
handleClick = (event, ctx) => {
event.preventDefault() // 屏蔽掉默认的a标签的事件
ctx.history.push(this.props.to) // 手动执行history事件
}
render() {
const {children, to} = this.props
return (
<RouteConsumer>
{
(ctx) => (
<a href={to} onClick={event => this.handleClick(event, ctx)}>
{children}
</a>
)
}
</RouteConsumer>
);
}
}
export function Route (props){
const ctx = useContext(RouteContext) // 因为是函数组件,所以调用useContext拿到传递的值
const {location} = ctx
const {component, path} = props // props是该组件接受到的传值参数
const matchRoute = location.pathname === path // 页面路径和传递来的路径相同则显示对应组件
return (
matchRoute && component ? React.createElement(component) : null // 通过React.createElement可以将component渲染出来
)
}