react-route简单实现

调用界面

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渲染出来
    )
}
原文地址:https://www.cnblogs.com/cazj/p/14267311.html