route
pathToRegexp
输入是路径字符串(也就是 Route 中定义的 path 的值),输出包含两部分
- 正则表达式(re)
 - 一个数组(keys)(用于记录 param 的 key 信息)
 
matchPath
参数:
pathname 当前页面的 url
options 当前 Route 的信息,必须有 path
执行过程
- matchPath 接收当前页面的 url,和当前 Route 的 path 属性
 - 调用 compilePath,接收当前 Route 的 path 属性和一些默认参数,
- 调用 pathToRegexp 方法,将当前的 Route 的 path 转换为一个正则表达式,
 - 返回一个包含正则表达式,和 keys 的对象
 
 - 根据 compilePath 返回的正则捕获当前页面的 url(pathname),如果当前 url 和 path 转换的正则匹配就返回一个数组,否则返回 null,
- 匹配成功, matchPath 返回一个包含 path,url,isExact,params 的 Object
 - 匹配失败,返回 null,matchPath 结束,返回 null
 
 
根据 matchPath 返回的结果,决定创建哪个组件,如果 null,则不创建
render
class Route extends React.Component {
    componentDidMount() {
        console.log("route===>", this.props);
    }
    render() {
        return (
            <RouterContext.Consumer>
                {context => {
                    invariant(
                        context,
                        "You should not use <Route> outside a <Router>"
                    );
                    const location = this.props.location || context.location;
                    const match = this.props.computedMatch
                        ? this.props.computedMatch // <Switch> already computed the match for us
                        : this.props.path
                        ? matchPath(location.pathname, this.props)
                        : context.match;
                    const props = { ...context, location, match };
                    let { children, component, render } = this.props;
                    // Preact uses an empty array as children by
                    // default, so use null if that's the case.
                    if (Array.isArray(children) && children.length === 0) {
                        children = null;
                    }
                    return (
                        <RouterContext.Provider value={props}>
                            {props.match
                                ? children
                                    ? typeof children === "function"
                                        ? __DEV__
                                            ? evalChildrenDev(
                                                  children,
                                                  props,
                                                  this.props.path
                                              )
                                            : children(props)
                                        : children
                                    : component
                                    ? React.createElement(component, props)
                                    : render
                                    ? render(props)
                                    : null
                                : typeof children === "function"
                                ? __DEV__
                                    ? evalChildrenDev(
                                          children,
                                          props,
                                          this.props.path
                                      )
                                    : children(props)
                                : null}
                        </RouterContext.Provider>
                    );
                }}
            </RouterContext.Consumer>
        );
    }
}
// 1. 判断是否匹配到,
if (props.match) {
    if (children) {
        if (typeof children === "function") {
            if (__DEV__) {
                evalChildrenDev(children, props, this.props.path);
            } else {
                children(props);
            }
        } else {
            // children
        }
    } else {
        if (component) {
            React.createElement(component, props);
        } else {
            if (render) {
                render(props);
            } else {
                null;
            }
        }
    }
} else {
    if (typeof children === "function") {
        if (__DEV__) {
            evalChildrenDev(children, props, this.props.path);
        } else {
            children(props);
        }
    } else {
        // null;
    }
}
- 组件接收 path,component/render 属性,
 - RouterContext.Consumer 提供的 context 包含 location,history 等属性
 - 使用组件的 path 和 context 的 location 进行匹配,匹配到就 React.createElement(component, props)/render(props),否则返回 null