如何通过动态导入使React.lazy / Suspense工作?

时间:2020-04-18 08:50:24

标签: reactjs

我知道我可以使用Suspense和所有这些东西进行延迟导入和渲染,但是在这种情况下会发生什么:

我有一个索引文件,该文件可以导出该文件夹中的所有文件:

export { default as Reactjs } from './Reactjs';
export { default as Bootstrap } from './Bootstrap';
export { default as Cypress } from './Cypress';
export { default as Firebase } from './Firebase';

and so on...

在路由器文件中,我已这样导入:

import * as Components from './components';

然后,我列出了要渲染的路线:

const routes = [
  'Reactjs',
  'ReactRouter',
  'Redux',
  'Materialui',
  'Socketio',

  ... and so on
];

这是我在每条路线上重复使用的代码:

    <Switch>
      <Route exact path={path} component={Frontend} />
      {routes.map((route) => (
        <Route
          key={route}
          path={`${path}/${route.toLowerCase()}`}
          component={Components[route]}
          exact
          {...props}
        />
      ))}
    </Switch>

在这种情况下,所有文件都捆绑在一起,我想使用React.lazy避免这种情况

我试图这样做,但是路由并没有捆绑在一起,当您导航到任何这些路由时,不会引发错误,只是没有内容,就永远不会呈现该组件。

我知道可以只在每个路由器组件中延迟导入并手动添加所有路由,并且它可以正常工作,但是该项目正在迅速发展,正在寻找通用解决方案,有什么想法吗?

解决方案

这里的重点是使用render方法而不是component。正如utils func所建议的那样,它是工作方式。

最终密码:

import React, { Suspense } from 'react';
import { Route, Switch } from 'react-router-dom';
import * as Components from './components';
import Frontend from './Frontend';

const routes = [
  'Reactjs',
  'ReactRouter',
  'Redux',
  'Materialui',
  'Socketio',
  'HTML5',
  'CSS3',
  'Victory',
  'Firebase',
  'Cypress',
  'Jest',
  'Enzyme',
  'StyledComponents',
  'Sass',
  'Javascript',
];
const path = '/developer/frontend';

const renderLazyComponents = (WrappedComponent, props) => (
  <Suspense fallback="Loading...">
    <WrappedComponent {...props} />;
  </Suspense>
);

const FrontendRoutes = (props) => {
  return (
    <Switch>
      <Route exact path={path} component={Frontend} />
      {routes.map((route) => (
        <Route
          key={route}
          path={`${path}/${route.toLowerCase()}`}
          render={(props) => renderLazyComponents(Components[route], props)}
          exact
          {...props}
        />
      ))}
    </Switch>
  );
};

export default FrontendRoutes;

先前的邮政编码:

  496.93 KB (-878 B)  build/static/js/2.4e310625.chunk.js
  28.2 KB (-7.41 KB)  build/static/js/main.fa528c14.chunk.js
  725 B               build/static/js/runtime-main.3ce8a40d.js
  574 B               build/static/css/main.13004e90.chunk.css

下一个邮政编码:

  497.9 KB (+986 B)    build/static/js/2.376eba4d.chunk.js
  34.98 KB (+6.78 KB)  build/static/js/main.94a280ad.chunk.js
  2.56 KB              build/static/js/3.b1f8eb5c.chunk.js
  1.26 KB (+567 B)     build/static/js/runtime-main.0ae647e3.js
  574 B                build/static/css/main.13004e90.chunk.css
  212 B                build/static/js/16.1903fd99.chunk.js
  208 B                build/static/js/11.adc04e6c.chunk.js
  206 B                build/static/js/12.c2f29dcb.chunk.js
  204 B                build/static/js/15.654cac3a.chunk.js
  204 B                build/static/js/17.6a7c5409.chunk.js
  204 B                build/static/js/4.e5aeca49.chunk.js
  204 B                build/static/js/8.e22f9199.chunk.js
  203 B                build/static/js/13.2bc7ba5b.chunk.js
  203 B                build/static/js/6.4d3d0771.chunk.js
  203 B                build/static/js/9.59059160.chunk.js
  202 B                build/static/js/7.39b3929b.chunk.js
  201 B                build/static/js/14.d7fd54d7.chunk.js
  201 B                build/static/js/5.0c63c3bb.chunk.js
  200 B                build/static/js/10.5c3037d5.chunk.js

1 个答案:

答案 0 :(得分:1)

以简单的方式,您可以通过以下代码片段进行延迟加载:

const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <OtherComponent />
      </Suspense>
    </div>
  );
}

但是,如果您希望它变得通用,我建议像在项目中那样,在App.js中这样做。

     const OtherComponent = React.lazy(() => import('./OtherComponent'));

    <div className="app-body">
                            <Switch>

                                <Route
                                    path={routingPath}
                                    render={props =>
                                        ComponentUtils.getSuspenseFulLazyComponent(
                                            <OtherLandingPage
                                                {...props}

                                            />
                                        )
                                    }
                                />
                       ....
                       ....
                       ....

</Switch>

现在在ComponentUtils.js文件中,编写以下通用函数:

import React, { Suspense } from 'react'
import LazyLoad from 'react-lazyload'
import BlockUi from 'react-block-ui'

export default class ComponentUtils {
    static getSuspenseFulLazyComponent(component, shouldLazyLoad, lazyLoadOffset) {
        return (
            <Suspense
                fallback={
                    <BlockUi tag="div" blocking={true}>
                        {' '}
                    </BlockUi>
                }
            >
                {!shouldLazyLoad ? component : <LazyLoad offset={100}>{component}</LazyLoad>}
            </Suspense>
        )
    }
}

我希望该解决方案可以帮助您找到自己的出路!!!!