react-router英雄指南

878 阅读3分钟

1.2.6. react-router

阐述hashHistory与browserRouter的区别

  • Router组件的history属性,用来监听浏览器地址栏的变化,并将URL解析成一个地址对象,供 React Router 匹配。
  • history属性,一共可以设置三种值。
    • browserHistory
    • hashHistory
    • createMemoryHistory
  • 如果设为hashHistory,路由将通过URL的hash部分(#)切换,URL的形式类似example.com/#/some/path
  • 如果设为browserHistory,浏览器的路由就不再通过Hash完成了,而显示正常的路径example.com/some/path,背后调用的是浏览器的History API。
    • 但是,这种情况需要对服务器改造。否则用户直接向服务器请求某个子路由,会显示网页找不到的404错误。
    • 如果开发服务器使用的是webpack-dev-server,加上--history-api-fallback参数就可以了。
  • createMemoryHistory主要用于服务器渲染。它创建一个内存中的history对象,不与浏览器URL互动。

阐述Router、Route相关API的用法

  • Router(路由器)就是react的一个组件,本身只是一个容器,真正的路由要通过Route组件定义
import { Router, Route, hashHistory } from 'react-router';

render((
  <Router history={hashHistory}>
    <Route path="/" component={App}/>
  </Router>
), document.getElementById('app'));
  • Route组件还可以嵌套,Route组件的path属性指定路由的匹配规则。这个属性是可以省略的,这样的话,不管路径是否匹配,总是会加载指定组件。

如何渲染多层级路由

  • 渲染多层级路由可在Route组件中嵌套Route组件,执行时先加载外部App组件,然后在它的内部加载子组件,在外部组件中使用this.props.children属性代表子组件
<Router history={hashHistory}>
  <Route path="/" component={App}>
    <Route path="/repos" component={Repos}/>
    <Route path="/about" component={About}/>
  </Route>
</Router>

App组件:

export default React.createClass({
  render() {
    return <div>
      {this.props.children}
    </div>
  }
})
  • 子路由也可以不写在Router组件里面,单独传入Router组件的routes属性
let routes = <Route path="/" component={App}>
  <Route path="/repos" component={Repos}/>
  <Route path="/about" component={About}/>
</Route>;

<Router routes={routes} history={browserHistory}/>

阐述路由变化到组件更新的整个过程

  • BrowserRouter 将会监听 URL 的变化,当 URL 变更时,它将使浏览器显示相应的页面
  • 导入BrowserRouter ,使用<BrowserRouter>包含住<App>,将导入所有的其他组件以便更好的协作,并监听 URL,确保当 URL 变更时通知其他组件。
  • 使用BrowserRouter时,其实真正的是在渲染Router组件并向其传递history属性,history库也是由React Training构建,目标是抽象化不同环境的区别,并提供最少的API来使你管理历史记录堆、导航、确认导航,并在会话之间保持状态。
  • 总之,要使ReactRouter正常工作,需要将整个应用封装在 BrowserRouter组件中,BrowserRouter还会封装history库,使你的应用能够知道URL中的变化。
  • 先导入Link组件,通过link组件传递to属性,告诉应用要路由到哪个部分,组件会渲染成拥有相应的href的锚点标签a,因此,它的行为和网络上的普通链接的行为一致。
  • Route 接受一个路径,将会匹配(也可能不匹配)当前的URL,如果路径匹配URL,则Router会渲染一些UI,不匹配则不会渲染,通过检查URL,来决定要渲染哪个组件,这也意味着,回退按钮也可以正常工作了。

阐述history的底层机制

  • 利用History_API,进行路由切换, 在mdn上提到了history栈,说明它的存储形势是个栈结构
1. history.pushState(stateObject, title, url) 用于路径的跳转(也就是向history栈添加数据)
2. history.replaceState() 用于修改栈中某个记录的数据
3. onpopstate: 每当活动的历史记录项发生变化时, popstate 事件都会被传递给window对象