react router

react router

1、Router组件

1.1 属性

children结点

history

必传对象

staticContext

对象

router作为context的提供者。其有两层context

render() { return ( <RouterContext.Provider value={{ history: this.props.history, location: this.state.location, match: Router.computeRootMatch(this.state.location.pathname), staticContext: this.props.staticContext }} > <HistoryContext.Provider children={this.props.children || null} value={this.props.history} /> </RouterContext.Provider> ); } }

BrowserRouter和HashRouter基本骨架是一样的,除了history属性,BrowserRouter的history是通过createBrowserHistory创建,而HashRouter的history是通过createHashHistory创建

路由提供者的对象成员有

  • history,其也会作为history的提供值

    action: Action location: Location createHref(to: To): string push(to: To, state?: any): void replace(to: To, state?: any): void go(delta: number): void back(): void forward(): void isten(listener: Listener): () => void block(blocker: Blocker): () => void
  • location

  • match

  • staticContext

1.2 路由对象

StaticRouter:用在服务端渲染

其属性有

属性名说明
basename路由的前缀名

context

上下文信息

location

url信息

2、Route组件

2.1 属性

children函数或者结点
exact布尔类型
location对象
path字符串或者字符串数组
render函数
sensitive布尔值
strict布尔值
component组件

children和component同时配置时,component会被忽略

children和render同时配置时,render会被忽略

route组件中基于router的context以及route组件的属性来构造给路由对应组件的消费的属性,其中包含context,location,match。其中match计算返回的一个包含以下属性的对象

参数说明

path

路径

url

url的匹配部分

isExact

是否精确匹配

params

模板参数
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; function matchPath(pathname, options = {}) { if (typeof options === "string" || Array.isArray(options)) { options = { path: options }; } const { path, exact = false, strict = false, sensitive = false } = options; const paths = [].concat(path); return paths.reduce((matched, path) => { if (!path && path !== "") return null; if (matched) return matched; const { regexp, keys } = compilePath(path, { end: exact, strict, sensitive }); const match = regexp.exec(pathname); if (!match) return null; const [url, ...values] = match; const isExact = pathname === url; if (exact && !isExact) return null; return { path, // the path used to match url: path === "/" && url === "" ? "/" : url, // the matched portion of the URL isExact, // whether or not we matched exactly params: keys.reduce((memo, key, index) => { memo[key.name] = values[index]; return memo; }, {}) }; }, null); }

其计算匹配依赖path-to-regexp库

2.2 element和component区别

element是react router v6的写法

component是react router v5以及之前的写法

<Route path="/" component={Home} /> //v5 <Route path="/" element={<Home />} /> //v6

3、Switch组件

作为Router的context的消费者,在子结点中找到匹配路径的route返回

class Switch extends React.Component { render() { return ( <RouterContext.Consumer> {context => { invariant(context, "You should not use <Switch> outside a <Router>"); const location = this.props.location || context.location; let element, match; // We use React.Children.forEach instead of React.Children.toArray().find() // here because toArray adds keys to all child elements and we do not want // to trigger an unmount/remount for two <Route>s that render the same // component at different URLs. React.Children.forEach(this.props.children, child => { if (match == null && React.isValidElement(child)) { element = child; const path = child.props.path || child.props.from; match = path ? matchPath(location.pathname, { ...child.props, path }) : context.match; } }); return match ? React.cloneElement(element, { location, computedMatch: match }) : null; }} </RouterContext.Consumer> ); } }