标签搜索

React按需加载

cicaba
2018-05-06 / 0 评论 / 0 阅读 / 正在检测是否收录...

1.Bundle.js
Bundle组件会接受一个名为 load 的 props
load值一是一个组件异步加载的方法 load -> function (cb) {...cb(/ 异步加载的组件 /)},由bundle-loader封装
这个方法需要传入一个回调函数作为参数
回调函数会在在方法内异步接收加载完的组件

import React from 'react';  
  
class Bundle extends React.Component {  
  constructor(props){  
    super(props);  
    this.state = {  
      // 默认为空  
      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({  
        mod: mod.default ? mod.default : mod  
      });  
    });  
  }  
  
  render() {  
    // 不为空,则渲染传入的子组件函数  
    return this.state.mod ? this.props.children(this.state.mod) : null;  
  }  
}  
  
export default Bundle;  

2.lazyLoad.js
这个包装函数接受两个值,一个为经过bundle-loader封装的组件,另一个是组件的属性

import React from 'react';  
import Bundle from './Bundle';  
  
  
// 默认加载组件,可以直接返回 null   
const Loading = () => <div>Loading...</div>;  
  
  
/* 
   包装方法,第一次调用后会返回一个组件(函数式组件) 
   由于要将其作为路由下的组件,所以需要将 props 传入 
      <Bundle load={loadComponent}> 
      {Comp => (Comp ? <Comp {...props} /> : <Loading />)} 
   </Bundle> 
*/   
const lazyLoad = (loadComponent,props) =>  
{//Bundle  包含的是一个函数子组件 由Bundle.js里的this.props.children(this.state.mod)渲染  
  return(  
   <Bundle load={loadComponent}>  
      {Comp => (Comp ? <Comp {...props} /> : <Loading />)}  
   </Bundle>  
);}  
  
export default lazyLoad;  

3.路由使用
有两种使用方式,一种是webpack配置(见下面第四点),
另一种是在组件内直接引用bundle-loader(下面代码没注释的就是)

//import Home from './page/Home.bundle';//这种方式需要配置webpack的loader  
//import Detail from './page/Detail.bundle';//这种方式需要配置webpack的loader  
  
//--------------------------------------------------  
  
import Detail from 'bundle-loader?lazy&name=home!./page/Detail.bundle';  
import Home from 'bundle-loader?lazy&name=home!./page/Home.bundle';  
  
<BrowserRouter>  
  <div>  
  
  
      <Route exact  path="/" render={()=>     
        <Redirect to="/home"/>                 
        // <Home dispatch={dispatch} getState={getState} questionList={value.question}></Home>  
      }/>  
      <Route path="/home" render={()=>{  
        return lazyLoad(Home, {  
            dispatch:dispatch,  
            getState:getState,  
            questionList:value.question  
          }  
        );  
      }}/>                           
      <Route path="/detail" render={(props)=>{  
        return lazyLoad(Detail, {  
                    pid:props.location.id,  
                    questionList:value.question,  
                    dispatch:dispatch,  
                    answer:value.answer  
                }  
              );  
      }}/>  
  </div>  
</BrowserRouter>   

4.如果使用webpack配置
注意这段代码要放在js的loader之前,不然可能会报错,这段配合下面这两句引用使用
//import Home from './page/Home.bundle';//这种方式需要配置webpack的loader
//import Detail from './page/Detail.bundle';//这种方式需要配置webpack的loader
[html] view plain copy

{  
  test: /\.bundle\.js$/,  
  loader: 'bundle-loader',  
  options: {  
    lazy: true,  
    name: '[name]'  
  }  
0

评论 (0)

取消