代码之家  ›  专栏  ›  技术社区  ›  ronnyrr

用Lazy+Suspense反应预加载组件

  •  3
  • ronnyrr  · 技术社区  · 7 年前

    在下面的例子中,我有两条路线。有没有预加载的方法 Demo 尽快 Prime componentDidMount 质数 React.lazy 似乎没有得到与下面的动态导入相同的文件。

    import React, { lazy, Suspense } from 'react';
    import { Switch, Route, withRouter } from 'react-router-dom';
    import GlobalStyle from 'styles';
    
    import Loading from 'common/Loading';
    const Prime = lazy(() => import(/* webpackChunkName: "Prime" */'modules/Prime'));
    const Demo = lazy(() => import(/* webpackChunkName: "Demo" */'modules/Demo'));
    
    const App = () => (
      <main>
        <GlobalStyle />
        <Suspense fallback={<Loading>Loading...</Loading>}>
          <Switch>
            <Route path="/" component={Prime} exact />
            <Route path="/demo" component={Demo} />
          </Switch>
        </Suspense>
      </main>
    );
    
    export default withRouter(App);
    

    所以我尝试了不同的方法,比如有和没有 webpackChunkName 以及导入其他组件的不同方法 组件didmount 组件didmount 导致在下图底部显示的网页包错误。只有第三个继续了,但留下了文件 2.[hash].js 在图像中,只有在页面被访问后才加载,而不是打开 组件didmount

    enter image description here

    我错过了什么?

    代码 modules/Demo.jsx :

    import React from 'react';
    
    import LogoIcon from 'vectors/logo.svg';
    import PageLink from 'common/PageLink';
    import Anchor from 'common/Anchor';
    import CenteredSection from 'common/CenteredSection';
    
    const Demo = () => (
      <CenteredSection variant="green">
        <LogoIcon />
        <PageLink to="/" variant="green">Go to home page</PageLink>
      </CenteredSection>
    );
    
    export default Demo;
    
    1 回复  |  直到 7 年前
        1
  •  6
  •   James Friedman    6 年前

    这是非常容易做到的,我认为人们对lazy()和Suspense在幕后做什么有误解。

    React.lazy(() => Promise<{default: MyComponent}>)
    

    所以如果你想预装,你所要做的就是提前执行承诺。

    // So change this, which will NOT preload
    import React from 'react';
    const MyLazyComp = React.lazy(() => import('./path/to/component'));
    
    /*********************************************/
    
    // To this, which WILL preload
    import React from 'react';
    
    // kicks off immediately when the current file is imported
    const componentPromise = import('./path/to/component');
    
    // by the time this gets rendered, your component is probably already loaded
    // Suspense still works exactly the same with this.
    const MyLazyComp = React.lazy(() => componentPromise);
    

    事实上,这是一个已知的签名,这使得它在其他各种情况下都很有用。例如,我有一堆依赖于googlemapsapi的组件被动态加载,我能够创建一个加载googlemapsapi然后导入组件的函数。我将不详细介绍这个例子的内部,因为它是一个切线,但重点是我自己创建了一个函数,它执行一系列异步操作,然后返回一个对象为{default:Component}的Promise。

    import React from 'react';
    const MyLazyComp = React.lazy(() => importMapsComponent('./path/to/comp'));
    
        2
  •  1
  •   Ryan Cogswell    7 年前

    code sandbox 这是可行的(Demo由componentDidMount加载)。这是一个相当简化的版本,使用createreact app进行配置。也许你可以把它作为一个起点,逐渐使它更接近你的应用程序,看看是什么原因导致动态导入不再按预期工作。

    推荐文章