有没有办法用 ESModule 延迟导出文件?

Is there a way to lazy export file with ESModule?

我有一个项目有很多文件要导出。现在我使用 CommonJS 延迟导出这些文件:

module.exports = {
  get AccessibilityInfo() {
    return require('../Components/AccessibilityInfo/AccessibilityInfo');
  },
  get ActivityIndicator() {
    return require('../Components/ActivityIndicator/ActivityIndicator');
  },
  // .... many other files 
 }

ReactNative 做同样的事情React Native,这样一个文件只在特定导入时加载。

我想用 ESModule 重构这个文件,但是我找不到懒惰导出文件的方法。
有没有办法使用 ESModule 延迟导出文件?
是否有必要使用 ESModule 延迟导出文件?

执行此操作的 ECMAScript 方法是通过动态 import()。语法基本上是一样的,它做你所期望的,除了它 returns 一个 promise (这很好 - 这意味着该操作不会锁定线程).您的代码可以例如看起来像这样:

export const getAccessibilityInfo = () =>
  import("../Components/AccessibilityInfo/AccessibilityInfo");

export const getActivityIndicator = () =>
  import("../Components/ActivityIndicator/ActivityIndicator");

然后您将像这样获取这些模块:

import { getActivityIndicator } from "./the/module/above";

const ActivityIndicatorPromise = getActivityIndicator();

// Whenever you need to use the ActivityIdicator module, you first need to await for the promise resolution

ActivityIndicatorPromise.then(ActivityIndicatorModule => {
  // Do what you want here...
});

您可以在此处阅读更多相关信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Dynamic_Imports。它还列出了这种语法更可取的情况。如果您希望使用静态导入语法 (import X from '../whatever';) 可以做到这一点,请放心——事实并非如此。

不, 在 React Native 中没有延迟导出的方法

导出对性能没有影响

import/require 文件必须成为 JS Bundle

的一部分

存在于内存中的组件会影响性能

在我看来,可以通过三种方式获得良好的性能

解决方案 1:动态导入

但是你只能像这样动态加载组件

const allPaths = {
  path1: require('file path1').default,
  path2: require('file path2').default
};

const MyComponent = allPaths('path1')

allPaths('path1') 在这种情况下只有 path1 组件将处于活动状态

_

解决方案 2:停止进一步渲染组件树

在特定条件下停止渲染,因此其他树不应在内存中处于活动状态并且不会对性能产生任何影响

render() {
    const {isReady} = this.state;
     if(!isReady)
     {
      return null;
     }

     return (
            <ActualComponent />
        )

}

-

解决方案3:Stop额外重新渲染

您可以使用 shouldComponentUpdate 来停止额外的重新渲染。仅在特定条件下的组件

shouldComponentUpdate(nextProps, nextState) {
  return this.state.name != nextState.name;
}