关于React Router

167 阅读3分钟

路由配置

React.render((
  <Router>
    <Route path="/" component={App}>
      <Route path="about" component={About} />
      <Route path="inbox" component={Inbox}>
        <Route path="messages/:id" component={Message} />
      </Route>
    </Route>
  </Router>
), document.body)

通过path属性和component属性,可以配置url对应的路由。

此时,当url为'/'时,我们会渲染App组件,但这时this.props.children是undefined,这种情况下,我们可以使用IndexRoute设置默认页面。

React.render((
  <Router>
    <Route path="/" component={App}>
      <IndexRoute component={Dashboard}/>
      <Route path="about" component={About} />
      <Route path="inbox" component={Inbox}>
        <Route path="messages/:id" component={Message} />
        {/* 使用 /messages/:id 替换 messages/:id */}
        {/*<Route path="/messages/:id" component={Message} />*/}
        {/*<Redirect from="messages/:id" to="/messages/:id" />*/}
      </Route>
    </Route>
  </Router>
), document.body)

如果我们想url为/message/:id也能正常访问,那么只需使用 /messages/:id 替换 messages/:id,但这样做会导致url被改变,当我们访问/inbox/message/:id时,会得到错误的页面。要解决这个问题,我们还要加一个Redirect标签。

Router中的history属性

history知道如何监听浏览器地址的变化,并解析这个url转化为location对象,然后router使用它匹配到路由,最后正确渲染组件。

  • browserHistory

    是使用react router的应用推荐的history,它使用浏览器中的 History API 用于处理 URL,创建一个像example.com/some/path这样真实的 URL。当URL发生变化的时候,会向服务器发送request请求。对多页面模式应用(MPA),浏览器会通过自身的history处理好页面间的操作,但对于单页面应用(SPA),只有一个真实的HTML页面,是无法体现页面跳转效果的,这时,需要服务器配合,模拟出多个HTML页面,从而实现浏览器真实的页面跳转效果。

  • hashHistory

    Hash history 使用 URL 中的 hash(#)部分去创建形如 example.com/#/some/path 的路由。不需要服务器的任何配置就可以运行。

  • createMemoryHistory

    Memory history 不会在地址栏被操作或读取。这就解释了我们是如何实现服务器渲染的。同时它也非常适合测试和其他的渲染环境(像 React Native )。

    和另外两种history的一点不同是你必须创建它,这种方式便于测试。

    const history = createMemoryHistory(location)
    

react-router-dom

react-router实现了路由的核心功能,而react-router-dom则基于react-router,加入了浏览器环境下的一些功能,比如说Link组件、BrowserRouter和HashRouter组件。但类似Switch、Route这样的组件,react-router-dom都是从react-router中引入,然后重新导出而已。因此,我们在npm安装时,不用再显示安装react-router了。

Switch组件

会从上往下匹配它包裹的Route中的path,渲染第一个匹配的URL。

Route组件

他的path属性总是匹配url的前缀,因此path='/'会匹配任何url,因此我们要把这一条route放在switch的最后或者使用exact关键字修饰。

react-router-dom的hooks

useHistory

获取history实例,通过history.push()方法跳转路由。

useLocation

返回一个location对象,包含当前url的信息。

useParams

返回键值对对象,包含匹配到的路由中的参数。

useRouteMatch

和一样用来匹配当前URL,但是不会渲染对应的组件,只是返回match对象。

withRouter

使用这个高阶组件,就可以从props中获取到match,location和history的信息。在外部可以通过WrappedComponent这个静态属性获取到原来的组件。