react-router4中異步加載路由的方法有哪些

小編給大家分享一下react-router4中異步加載路由的方法有哪些,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

創(chuàng)新互聯(lián)是一家專注于成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)與策劃設(shè)計(jì),高州網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:高州等地區(qū)。高州做網(wǎng)站價(jià)格咨詢:18980820575

方法一:我們要借助bundle-loader來(lái)實(shí)現(xiàn)按需加載。

首先,新建一個(gè)bundle.js文件:

import React, { Component } from 'react'

export default class Bundle extends React.Component {

  state = {
    // short for "module" but that's a keyword in js, so "mod"
    mod: null
  }

  componentWillMount() {
    this.load(this.props)
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.load !== this.props.load) {
      this.load(nextProps)
    }
  }

  load(props) {
    this.setState({
      mod: null
    })
    props.load((mod) => {
      this.setState({
        // handle both es imports and cjs
        mod: mod.default ? mod.default : mod
      })
    })
  }

  render() {
    if (!this.state.mod)
      return false
    return this.props.children(this.state.mod)
  }
}

然后,在入口處使用按需加載:

// ...

// bundle模型用來(lái)異步加載組件
import Bundle from './bundle.js';

// 引入單個(gè)頁(yè)面(包括嵌套的子頁(yè)面)
// 同步引入
import Index from './app/index.js';
// 異步引入
import ListContainer from 'bundle-loader?lazy&name=app-[name]!./app/list.js';

const List = () => (
  <Bundle load={ListContainer}>
    {(List) => <List />}
  </Bundle>
)

// ...

  <HashRouter>
    <Router basename="/">
      <div>
        <Route exact path="/" component={Index} />
        <Route path="/list" component={List} />
      </div>
    </Router>
  </HashRouter>

// ...


webpack.config.js文件配置
output: {
  path: path.resolve(__dirname, './output'),
  filename: '[name].[chunkhash:8].bundle.js',
  chunkFilename: '[name]-[id].[chunkhash:8].bundle.js',
},

方法二:用原生的

Webpack 配置

首先在 webpack.config.js 的 output 內(nèi)加上 chunkFilename

output: {
  path: path.join(__dirname, '/../dist/assets'),
  filename: 'app.js',
  publicPath: defaultSettings.publicPath,
  // 添加 chunkFilename
  chunkFilename: '[name].[chunkhash:5].chunk.js',
},

name 是在代碼里為創(chuàng)建的 chunk 指定的名字,如果代碼中沒(méi)指定則 webpack 默認(rèn)分配 id 作為 name。

chunkhash 是文件的 hash 碼,這里只使用前五位。

在路由頁(yè)面

這里寫的是舊的沒(méi)按需要加載的路由寫法

ReactDOM.render(
 (
  <Router history={browserHistory}>
   {/* 主頁(yè) */}
   <Route path="/" component={App}>
    {/* 默認(rèn) */}
    <IndexRoute component={HomePage} />

    {/* baidu */}
    <Route path="/baidu" component={BaiduPage}>
     <Route path="result" component={BaiduResultPage} />
     <Route path="frequency" component={BaiduFrequencyPage} />
    </Route>

    {/* 404 */}
    <Route path='/404' component={NotFoundPage} />
    
    {/* 其他重定向到 404 */}
    <Redirect from='*' to='/404' />
   </Route>
  </Router>
 ), document.getElementById('app')
);

我們需要讓路由動(dòng)態(tài)加載組件,需要將 component 換成 getComponent

ReactDOM.render(
 (
  <Router history={browserHistory}>
   {/* 主頁(yè) */}
   <Route path="/" component={App}>
    {/* 默認(rèn) */}
    <IndexRoute component={HomePage} />

    {/* baidu */}
    <Route path="/baidu"
          getComponent(nextState, cb) 
          { require.ensure([], (require) => { cb(null, require('components/layer/HomePage')) }, 'HomePage')}>
     <Route path="result"   getComponent... />
     <Route path="frequency" getComponent... />
    </Route>
    {/* 404 */}
    <Route path='/404' getComponent... />
    {/* 其他重定向到 404 */}
    <Redirect path='*' onEnter: (_, replaceState) => replaceState(null, "/404") />
   </Route>
  </Router>
 ), document.getElementById('app')
);

getComponent

對(duì)應(yīng)于以前的 component 屬性,但是這個(gè)方法是異步的,也就是當(dāng)路由匹配時(shí),才會(huì)調(diào)用這個(gè)方法。

這里面有個(gè) require.ensure 方法

require.ensure(dependencies, callback, chunkName)

這是 webpack 提供的方法,這也是按需加載的核心方法。第一個(gè)參數(shù)是依賴,第二個(gè)是回調(diào)函數(shù),第三個(gè)就是上面提到的 chunkName,用來(lái)指定這個(gè) chunk file 的 name。

如果需要返回多個(gè)子組件,則使用 getComponents 方法,將多個(gè)組件作為一個(gè)對(duì)象的屬性通過(guò) cb 返回出去即可。這個(gè)在官方示例也有,但是我們這里并不需要,而且根組件是不能返回多個(gè)子組件的,所以使用 getComponent。 

當(dāng)改寫之后,我們需要把這個(gè)重定向的路由單獨(dú)拆出來(lái),也就是 * 這個(gè)路由,我們上面已經(jīng)為他創(chuàng)建了一個(gè) redirect 目錄。這里使用到 onEnter 方法,然后在這個(gè)方法里改變路由狀態(tài),調(diào)到另外的路由,實(shí)現(xiàn) redirect :

/redirect/index.js

module.exports = {
 path: '*',
 onEnter: (_, replaceState) => replaceState(null, "/404")
}

The root route must render a single element

跟著官方示例和上面碼出來(lái)之后,可能頁(yè)面并沒(méi)有渲染出來(lái),而是報(bào) The root route must render a single element 這個(gè)異常,這是因?yàn)?module.exports 和 ES6 里的 export default 有區(qū)別。

如果你是使用 es6 的寫法,也就是你的組件都是通過(guò) export default 導(dǎo)出的,那么在 getComponent 方法里面需要加入.default。

getComponent(nextState, cb) {
  require.ensure([], (require) => {
   // 在后面加 .default
   cb(null, require('components/layer/ReportPage')).default
  }, 'ReportPage')
}

如果你是使用 CommonJS 的寫法,也就是通過(guò) module.exports 導(dǎo)出的,那就無(wú)須加 .default 了。

以上是“react-router4中異步加載路由的方法有哪些”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

分享題目:react-router4中異步加載路由的方法有哪些
標(biāo)題來(lái)源:http://bm7419.com/article48/iihphp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供、網(wǎng)站設(shè)計(jì)公司標(biāo)簽優(yōu)化、面包屑導(dǎo)航網(wǎng)站營(yíng)銷、做網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都app開(kāi)發(fā)公司