本篇文章来自:方一鸣
要实现哪些内容?
BrowserRouter
Route
Link
Switch
withRouter
useHistory
useLocation
useParams
useRouteMatch
React-router可以动态路由,也可以嵌套路由,无论我们在那个页面写路由,都可以进行跳转,核心原理基于React的Context,首先我们先创建一个Context文件
import React from 'react';
export const RouterContext = React.createContext();
接下来,我们要分析react-router实现了什么:
BrowserRouter: 是一个容器,真正进行有用的是props.children
Router: 也是一个容器,监听路由的变化,提供history,location,match的上下文内容
Link: 本质上是一个a标签,我们要将''to''内容替换到 href中,在props.children显示相对的内容
Switch: 返回第一个匹配的内容
Route: 渲染组件三种方式 component, render, children
Redirect: 路由重定向,注意组件的执行顺序(很重要)
withRouter: 高阶组件,给组件传递路由相关的API方法
Hooks相关API:函数组件获取history, location, params, match
Route先来实现以下Router,这是react-router核心组件之一,监听路由的变化,引起页面的刷新,达到切换地址更新组件渲染,
思考🤔:为什么要在constructor里面监听呢?
源码中已经给出了答案:
This is a bit of a hack. We have to start listening for location changes here in the constructor in case there are anys on the initial render. If there are, they will replace/push when they mount and since cDM fires in children before parents, we may get a new location before theis mounted.
大致意思是 因为Redirect的存在,子节点比父节点先要渲染,当路由redirect的时候 如果在componentDidMount写监听函数,会执行失败
import React, { Component } from 'react';
import { RouterContext } from './RouterContext'
export default class Router extends Component {
static computeRootMatch(pathname) {
return {path: '/', url: '/', params: {}. isExact: pathname === '/'}
const