欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 高考 > React@16.x(48)路由v5.x(13)源码(5)- 实现 Switch

React@16.x(48)路由v5.x(13)源码(5)- 实现 Switch

2024/10/24 4:49:48 来源:https://blog.csdn.net/qq_40147756/article/details/140064498  浏览:    关键词:React@16.x(48)路由v5.x(13)源码(5)- 实现 Switch

目录

  • 1,原生 Switch 的渲染内容
  • 2,实现

1,原生 Switch 的渲染内容

对如下代码来说:

import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
function News() {return <div className="page news">News</div>;
}function Goods() {return <div className="page goods">Goods</div>;
}export default function App() {return (<Router><Switch><Route path="/page1" component={News}></Route><Route path="/page2" component={Goods}></Route></Switch></Router>);
}

React 插件展示的内容:

在这里插入图片描述

可以看到,除了也使用了 Router 的上下文之外,只加载了一个 Route 组件

2,实现

经测试,Switch 的子元素有如下规则:

  • 如果不是 Route 组件,则会报错。
  • 如果只有一个 Route 组件,则得到的 props.children 的类型是对象
  • 如果有多个 Route 组件,则得到的 props.children 的类型是数组。

所以,除了做以上特殊的判断外,再加上渲染第一个匹配到的组件的逻辑即可。

import React, { Component } from "react";
import ctx from "./RouterContext";
import { Route } from "./Route";
import matchPath from "./matchPath";export class Switch extends Component {getChildren = ({ location }) => {let children = [];if (Array.isArray(this.props.children)) {children = this.props.children;} else if (typeof this.props.children === "object") {children = [this.props.children];}for (const child of children) {if (child.type !== Route) {throw new TypeError("子元素非 Route 组件");}const { path = "/", exact = false, strict = false, sensitive = false } = child.props;const result = matchPath(path, location.pathname, {exact,strict,sensitive,});if (result) {return child;}}return null;};render() {return <ctx.Consumer>{this.getChildren}</ctx.Consumer>;}
}

注意到,判断是否是 Route 组件,可通过引入的 Route 组件直接进行判断。

在这里插入图片描述


以上。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com