react-router简易实现

利用context hashchange 实现router

大致思路如下

  • 利用context保证唯一路由信息,以及传递路由信息
  • 监听hashchange 修改当前路由信息

ps 以下代码都是基于hooks,而且只实现了HashRouter,如果要实现BrowserRouter就要监听popstate事件

//HashRouter.js
import React, { useState, useEffect } from 'react';
import Context from "./context";
const HashRouter = (props) => {
const [location,setLocation]=useState({
    pathname: window.location.hash.slice(1) || "/", // 获取浏览器地址栏中的hash值,如果不存在则默认为"/"
    query: undefined
})
useEffect(()=>{
    window.addEventListener("hashchange", () => { // 监听浏览器地址栏hash值变化
        setLocation(
            {
                ...location,
                pathname: window.location.hash.slice(1) // 更新pathname
            }
        )
    });
},[])
const currentRoute = {
    location: location, 
    history: { // 新增一个history对象用于实现当前路由的切换
        push: (to) => {
            if (typeof to === "object") { // 如果to是一个对象
                let { pathname, query } = to; // 取出pathname和query
                window.location.hash = pathname; // 更新浏览器hash值,触发浏览器hashchange事件
                location.query = query; // 更新query
            } else { // 修改浏览器地址栏的hash值
                window.location.hash = to; // 更新浏览器hash值
            }
        }
    }
}
return (
    <Context.Provider value={currentRoute}>
        {props.children}
    </Context.Provider>
);
};
export default HashRouter;

//Route.js
import React, {useContext} from "react";
import Context from "./context";
const Route = (props) => {
const context=useContext(Context)
const currentRoutePath = context.location.pathname; // 从上下文中获取到当前路由的路径
const {path, component:Component} = props; // 获取给Route组件传递的props属性
const props2 = {
    ...context
}
if (currentRoutePath === path) {
    return (
        <Component {...props2}></Component>
    );
}
return null
};
export default Route;

完整代码地址:https://github.com/dz333333/toy–router
参考:https://segmentfault.com/a/1190000022250917

发表评论

您的电子邮箱地址不会被公开。