浅析react中的react-router和react-router-dom

React路由实现有两个包:

  1.react-router  https://reacttraining.com/react-router/

  2.react-router-dom

在 React 的使用中,我们一般要引入两个包,react 和 react-dom,那么 react-router 和react-router-dom 是不是两个都要引用呢?
非也,坑就在这里。他们两个只要引用一个就行了,不同之处就是后者比前者多出了 <Link> <BrowserRouter> 这样的 DOM 类组件。
因此我们只需引用 react-router-dom 这个包就行了。如果你会用到 DOM 绑定的话。

  1.项目中用到的是:

  <Router>:它位于最外层,作用是使UI和URL保持同步,要实现这一点需要向Router组件写入history属性值,Router的history属性有两个值:browserHistory和hashHistory

   browserHistory和hashHistory的区别?

        更改路由的方式不同

     1.browserHistory 使用的是 HTML5 的 pushState API来修改浏览器的历史记录

     2.hashHistory 是通过改变地址后面的 hash(也就是URL中#后面的值) 来改变浏览器的历史记录。

       两种方式的特点

     1.History API 提供了 pushState() 和 replaceState() 方法来增加或替换历史记录。而 hash 没有相应的方法,所以browserHistory有替换历史记录的功能,hashHistory没有

     2hashHistory实现简单,不需要做额外的服务端改造(react browserHistory 完整部署方案:https://www.jianshu.com/p/77a5acfbc289

  <Link>:跳转到指定路径

跳转到指定路径:
<Link to="/courses" />


携带参数跳转到指定路径: <Link to={{ pathname: '/course', search: '?sort=name', state: { price: 18 } }} />

获取路由参数:
   this.props.location.state
   this.props.location.search

  <Route>:当页面的访问地址与 Route 上的 path 匹配时,就渲染出对应的 UI 界面。

component
只有当访问地址和路由匹配时,一个 React component 才会被渲染,此时此组件接受 route props (match, location, history)。
当使用 component 时,router 将使用 React.createElement 根据给定的 component 创建一个新的 React 元素。这意味着如果你使用内联函数(inline function)传值给 component将会产生不必要的重复装载。对于内联渲染(inline rendering), 建议使用 renderprop。
<Route path="/user/:username" component={User} />
const User = ({ match }) => {
  return <h1>Hello {match.params.username}!</h1>
}

render: func
此方法适用于内联渲染,而且不会产生上文说的重复装载问题。
// 内联渲染
<Route path="/home" render={() => <h1>Home</h1} />
 
// 包装 组合
const FadingRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => (
    <FadeIn>
      <Component {...props} />
    </FaseIn>
  )} />
)
 
<FadingRoute path="/cool" component={Something} />

children: func 有时候你可能只想知道访问地址是否被匹配,然后改变下别的东西,而不仅仅是对应的页面。 <ul> <ListItemLink to="/somewhere" /> <ListItemLink to="/somewhere-ele" /> </ul> const ListItemLink = ({ to, ...rest }) => ( <Route path={to} children={({ match }) => ( <li className={match ? 'active' : ''}> <Link to={to} {...rest} /> </li> )} )

  <Switch>:只渲染出第一个与当前访问地址匹配的 <Route> 或 <Redirect>。下的子节点只能是 <Route> 或 <Redirect> 元素

  <Redirect>:<Redirect> 渲染时将导航到一个新地址,这个新地址覆盖在访问历史信息里面的本该访问的那个地址。

  2.从Link组件和a标签的区别说起

    (1):对比<a>,Link组件避免了不必要的重渲染

    (2):react-router:只更新变化的部分从而减少DOM性能消耗

         react的创新之处在于,它利用虚拟DOM的概念和diff算法实现了对页面的"按需更新",react-router很好地继承了这一点,譬如上图所示,导航组件和三个Tab组件(通过...,通过...,通过...)的重渲染是我们不希望看到的,因为无论跳转到页面一或是页面二,它只需要渲染一次就够了。<Link>组件帮助我们实现了这个愿望,反观<a>标签,每次跳转都重渲染了导航组件和Tab组件试想一下,在一个浩大的项目里,这多么可怕!我们的"渲染"做了许多"无用功",而且消耗了大量弥足珍贵的DOM性能!

 

参考:https://blog.csdn.net/sinat_17775997/article/details/69218382

      https://blog.csdn.net/sinat_17775997/article/details/66967854

posted on 2019-10-12 21:43  Diamond_xx  阅读(429)  评论(0编辑  收藏  举报

导航