-
-
react-router-dom的目录结构:
因为在使用的时候是使用BrowserRouter或者HashRouter包裹所有的Route。 (不过还有个MemoryRouter这个我还不了解)
所以先看BrowserRouter或者HashRouter文件
-
BrowserRouter.js
import React from "react"; import { Router } from "react-router"; import { createBrowserHistory as createHistory } from "history"; /** * The public API for a <Router> that uses HTML5 history. */ class BrowserRouter extends React.Component { // 创建个history history = createHistory(this.props); render() { return <Router history={this.history} children={this.props.children} />; } } export default BrowserRouter;
- Router -- 目录
react-router/packages/react-router/modules/Router.js
- 创建history
- 监听 location,如果location发生改变,通过setState将子组件重新渲染;
- 通过context将history/location/
import React from "react"; import HistoryContext from "./HistoryContext.js"; import RouterContext from "./RouterContext.js"; /** * The public API for putting history on context. */ class Router extends React.Component { static computeRootMatch(pathname) { return { path: "/", url: "/", params: {}, isExact: pathname === "/" }; } constructor(props) { super(props); this.state = { location: props.history.location }; this._isMounted = false; this._pendingLocation = null; if (!props.staticContext) { //监听location -- 如果路由发生变化 那么子路由就会重新渲染 this.unlisten = props.history.listen(location => { if (this._isMounted) { this.setState({ location }); } else { this._pendingLocation = location; } }); } } componentDidMount() { this._isMounted = true; if (this._pendingLocation) { this.setState({ location: this._pendingLocation }); } } componentWillUnmount() { //取消监听 if (this.unlisten) { this.unlisten(); this._isMounted = false; this._pendingLocation = null; } } 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> ); } } export default Router;
history的createBrowserHistory方法 -- 返回一个 history 对象 --其实使用的是H5的history
```js // var globalHistory = window.history; var history={ length: globalHistory.length,// action: 'POP', location: initialLocation, createHref: createHref, push: push, replace: replace, go: go,// globalHistory.go(n); goBack: goBack, // go(-1); goForward: goForward, // go(1) block: block,// prompt listen: listen //监听 } ```
- 小结
- BrowserRouter 通过RouterContext (context ) 向所有子组件提供 history/location/match属性。
- BrowserRouter 通过history.listen 监听 location,如果路由发生变化通过this.setState({ location })更新location并提供给Route。
- 下一篇 route
-