美文网首页让前端飞redux学习React Native开发
react-router4按需加载踩坑,填坑

react-router4按需加载踩坑,填坑

作者: 墨子工程 | 来源:发表于2019-01-04 13:13 被阅读3次

    react-router4如何去实现按需加载Component,在router4以前,我们是使用getComponent的方式来实现按需加载的,router4中,getComponent方法已经被移除,网上有好几种方案大多都解决的不太彻底,下面我说一下我的方案:

    一:创建asyncComponent.js

    import React, { Component } from "react";
    
    export default function asyncComponent(importComponent) {
      class AsyncComponent extends Component {
        constructor(props) {
          super(props);
    
          this.state = {
            component: null
          };
        }
    
        async componentDidMount() {
          if(this.hasLoadedComponent()){
              return;
          }
          const { default: component } = await importComponent();
          this.setState({
            component: component
          });
        }
    
        hasLoadedComponent() {
            return this.state.component !== null;
        }
     
        render() {
          const C = this.state.component;
    
          return C ? <C {...this.props} /> : null;
        }
      }
    
      return AsyncComponent;
    }
    
    

    二:在引入asyncComponent.js,并导入需要按需加载的模块

      import asyncComponent from "utils/asyncComponent"
    
      const Home = asyncComponent(() => import("./home"))
      const About = asyncComponent(() => import("./about"))
    

    二:render部分

     const routes = () => (
        <BrowserRouter>
            <Switch>
                <Route exact path="/" component={Home} />
                <Route exact path="/about" component={About} />
                <Redirect to="/" />
            </Switch>
        </BrowserRouter>
    )
    

    三:预览效果


    image.png

    可以看到有一个警告,内容是
    Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method
    这个警告其实是在组件卸载的时候执行了setState,虽然这个警告并不影响正常使用,但是看着总是不爽,所以我们要在组件卸载的时候结束setState,如下:

    componentWillUnmount(){
        this.setState = (state,callback)=>{
            return
          }
    }
    

    四:完整版asyncComponent.js

    import React, { Component } from "react";
    
    export default function asyncComponent(importComponent) {
      class AsyncComponent extends Component {
        constructor(props) {
          super(props);
    
          this.state = {
            component: null
          };
        }
    
        async componentDidMount() {
          if(this.hasLoadedComponent()){
              return;
          }
          const { default: component } = await importComponent();
          this.setState({
            component: component
          });
        }
    
        hasLoadedComponent() {
            return this.state.component !== null;
        }
        componentWillUnmount(){
          this.setState = (state,callback)=>{
            return
          }
        }
    
        render() {
          const C = this.state.component;
    
          return C ? <C {...this.props} /> : null;
        }
      }
    
      return AsyncComponent;
    }
    
    

    五: webpack部分配置需要配置chunkFilename

    eturn {
        output: {
          path: path.resolve(CWD, config.build),
          publicPath: config.static[process.env.MODE],
          chunkFilename: 'js/[name]-[chunkhash:8].js',
          filename: 'js/[name].js',
        },
    

    结尾推广一下我的react-native开源项目:
    https://github.com/duheng/Mozi

    相关文章

      网友评论

        本文标题:react-router4按需加载踩坑,填坑

        本文链接:https://www.haomeiwen.com/subject/ljuhrqtx.html