原理:react-router 是依赖于第三方js库history。而我们平时输在浏览器的URL则被history转换为location对象,
然后react-router的Router 组件会在componentWillMount 生命周期中就调用了history.listen方法,从而达到当路由变化, 会去调用setState 方法,修改location。然后通过context传递给<Route>组件,Route组件内部就匹配传下来的nextContext,从而去渲染对应的路由组件。
常用的history有三种
- createHashHistory
- createBrowserHistory
- createMemoryHistory
createHashHistory使用 URL 中的 hash(#)部分去创建形如
example.com/#/some/path
的路由。没有相应的方法去替换历史记录的功能,并且并不知道 hash 部分的细节
createBrowserHistory使用浏览器中的 History API 用于处理 URL,创建一个像
example.com/some/path
这样真实的 URL 。并且浏览器提供相应的接口来修改浏览器的历史记录,若服务端支持History API ,这样服务端能获取请求细节。
题外话: 单页面应用时候如果用的是createBrowserHistory的话,那么需要服务端做404处理,指向index.html。或者尝试nginx有一个配置try-file 指向index。而hash就不会出现404,因为永远都是根路径。
我们主要看下history怎么对路由变化监听的 只针对createBrowserHistory
参考掘金大神 https://juejin.im/post/5d4a68f5e51d4561ae4da5c6
重点
从上面看出件监听的回调函数handlePopState ,其最终是通过setState 来触发路由监听者,其中notifyListeners 会调用所有的listen 的回调函数,从而达到通知监听路由变化的监听者。
react-router使用
就不一一赘述
路由器组件(<BrowserRouter>、<HashRouter>)
路由匹配组件(<Route>、<Switch>)
导航组件(<Link>、<NavLink>、<Redirect>)。