調用界面
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渲染出來
)
}
