目录
- 1,原生 Route 的渲染内容
- 2,实现
1,原生 Route 的渲染内容
对如下代码来说:
import { BrowserRouter as Router, Route } from "react-router-dom";
function News() {return <div>News</div>;
}function Goods() {return <div>Goods</div>;
}export default function App() {return (<Router><Route path="/page1" component={News}></Route><Route path="/page2" component={Goods}></Route></Router>);
}
React 插件展示的内容:
可以看到每个 Route
组件中,还会有一个 Router 上下文。
这是因为,每个 Route
组件匹配的 match
对象不同,所以得再提供一次。除此之外,history
和 location
这2个对象并没有发生变化。
2,实现
import React, { Component } from "react";
import ctx from "./RouterContext";
import matchPath from "./matchPath";export class Route extends Component {renderChildren = (ctx) => {const { children, render, component } = this.props;// children 无论是否匹配都会渲染,也可以是函数,if (children !== undefined && children !== null) {if (typeof children === "function") {return children(ctx);} else {return children;}}// 没有匹配到路径,同时 children 没有内容if (!ctx.match) {return null;}// render 属性if (typeof render === "function") {return render(ctx);}// 只有 component 属性有值if (component) {const Comp = component;return <Comp {...ctx}></Comp>;}return null;};matchRoute = (pathname) => {const { path, exact = false, strict = false, sensitive = false } = this.props;return matchPath(path || "/", pathname, {exact,strict,sensitive,});};/*** 上下文消费者函数* Route 组件中又会提供一个 Router 的上下文,* history 和 location 对象相同,match 对象会重新进行匹配。*/consumerFunc = (value) => {// 上下文对象定义在这里,当 Router 组件传递的上下文内容发生变化时,也会实时更新。const ctxValue = {history: value.location,location: value.location,match: this.matchRoute(value.location.pathname),};return <ctx.Provider value={ctxValue}>{this.renderChildren(ctxValue)}</ctx.Provider>;};render() {return <ctx.Consumer>{this.consumerFunc}</ctx.Consumer>;}
}
以上代码经过测试,和原生 Route
组件表现一致。
以上。