亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

升級到 React Router 4 并實現動態加載和模塊熱替換

標簽:
JavaScript

这篇文章是升级到Webpack2坑——模块热替换失效页面不自动刷新?的后续。那篇文章主要说明了,升级到 Webpack 2 之后,通过升级webpack-dev-serverreact-hot-loader插件,使模块热替换(HMR)再次生效。但后来发现,其实并没有完全生效。

问题

项目中的 Route 使用了System.import(/* webpackChunkName: "example" */ './example.js)来实现模块的动态加载,也就是根据组件打包成多个 bundle,只有在点击到对应的 Route 时,这个 bundle 才会被加载,而不是在打开首页时,加载所有的 bundle。

问题是,当我们修改某个标签页对应的组件时,会发现 HMR 并不是每次都生效。热替换过程会报错(类似[HMR] unexpected require(116) from disposed module 26),并且无法切换标签页了。

根据这篇讨论webpack2 + hot-reload: Not works with System.import,我决定升级 React Router 到v4并且将 System.import() 替换成 import()

升级到 React Router v4

版本变化:

  • webpack:2.7.0

  • react-hot-loader: 4.1.2

  • react:0.14.7  >>> 15.6.2

  • react-dom:0.14.7  >>> 15.6.2

  • react-router: 2.5.2 卸载,安装 react-router-dom 4.3.0-rc.3

reactreact-dom是顺便升级的,并不强制。主要的升级是 react-router v2到v4。在v4版本中, Web开发只需要安装react-router-dom,参考中的回答。
React Router v4变化挺大的。因此看官方文档(点
这里)是很有必要的。

动态路由(Dynamic Routing)

React Router从v4开始,不再是静态路由(Static Routing),而变成了动态路由(Dynamic Routing)。前者是我们习惯的用法,一般需要在应用初始化过程中声明路由,这时候页面还没有任何渲染;后者则意味着,路由会随着应用的渲染而发生,而不是一个在运行的应用之外的配置。React Router v4中的任何东西都是一个组件。

When we say dynamic routing, we mean routing that takes place as your app is rendering, not in a configuration or convention outside of a running app. That means almost everything is a component in React Router.

一开始看到这部分我还没太明白,直到我意识到,我不再需要在一个Root组件中定义所有的 Route,而是可以在任何组件内部添加一个 Route 时,我才弄懂这个“动态路由”的意思。就跟我们平时使用自定义的组件是一样的,想在哪里渲染,就加到哪里。参照示例Sidebar

You can render a <Route> in as many places as you want in your app. It will render along with any other <Route>s that also match the URL. So, a sidebar or breadcrumbs or anything else that requires you to render multiple things in multiple places at the same URL is nothing more than multiple <Route>s.

嵌套路由(Nested Routing)

v4版本以前,我们可能会用到嵌套路由,尤其是当页面中有导航栏时。比如:

<Route path='parent' component={Parent}>
  <Route path='child' component={Child} />
  <Route path='other' component={Other} /></Route>

当嵌套的内存路由匹配时,外层路由和内层路由对应的组件都会被渲染出来,而且子组件会通过props.children传递给父组件,也就是子组件会渲染到父组件 render 方法中{this.props.children}所在的位置。

v4版本时,就不需要在 Route 配置的地方嵌套好几个 Route,也不需要使用 this.props.children 指明子组件渲染的位置。只需要在父组件相应的位置添加 Route 即可。就跟嵌套一个 div 一样。

<Route path='parent' component={Parent} />const Parent = () => (  <div>
    //......    <Route path='child' component={Child} />
    <Route path='other' component={Other} />
  </div>)

重定向路由

v4去掉 <IndexRedirect>了。要实现重定向可以使用<Redirect>组件。

// v3<Route path="/" component={App}>  <IndexRedirect to="/welcome" /></Route>
// v4<Route exact path="/" render={() => <Redirect to="/welcome" component={App} />} />
//Switch限定只渲染第一个匹配的 Route<Switch>
  <Route exact path="/" component={App} />
  <Route path="/login" component={Login} />
  <Redirect path="*" to="/" />  //当以上的path均不匹配时,重定向到'/'</Switch>

局部刷新/整体刷新

局部刷新

<Link to='/home' />

整个页面刷新:

window.location.href = '/home'//or<a href='/home' ></a>

动态加载

修改前:

<Route path="/settings"
  getComponent={(location, callback) => {    import(/* webpackChunkName: "Settings" */ './Settings.js').then(component => {
      callback(null, component.default || component)
    })
  }}
  />

根据官方文档中的 Code Splitting 部分,实现动态加载需要 webpackbabel-plugin-systax-dynamic-import

综上就是升级过程的重点了。至此,动态加载和HMR都没问题了。



作者:Evelynzzz
链接:https://www.jianshu.com/p/25f8cb1d6276

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消