Skip to content

Allow for named imports in React.lazy #14603

Closed
@gnestor

Description

@gnestor

Do you want to request a feature or report a bug?

Feature

What is the current behavior?

Currently, React.lazy only accepts an anonymous function that returns a dynamic import object. readLazyComponentType then pulls the default export off of that import object. This does not allow for importing named imports from a module.

The official workaround, according to the React docs:

If the module you want to import uses named exports, you can create an intermediate module that reexports it as the default.

Another, more concise workaround:

const Contacts = React.lazy(() =>
  import('./Contacts.js').then(module => ({ default: module.Contacts }))
);

What is the proposed behavior?

I'd be willing to submit a PR that optionally accepts named imports but defaults to importing the default import. It would look like:

thenable.then(
-  moduleObject => {
+  resolvedComponent => {
    if (lazyComponent._status === Pending) {
-      const defaultExport = moduleObject.default;
+      if (resolvedComponent.default) {
+        resolvedComponent = resolvedComponent.default
+      }
      if (__DEV__) {
-        if (defaultExport === undefined) {
+        if (resolvedComponent === undefined) {
          warning(
            false,
-            'lazy: Expected the result of a dynamic import() call. ' +
+            'lazy: Expected a promise that resolves to a React component. ' +
              'Instead received: %s\n\nYour code should look like: \n  ' +
              "const MyComponent = lazy(() => import('./MyComponent'))",
-            moduleObject,
+            resolvedComponent,
          );
        }
      }
      lazyComponent._status = Resolved;
-      lazyComponent._result = defaultExport;
+      lazyComponent._result = resolvedComponent;
    }
  },
  error => {
    if (lazyComponent._status === Pending) {
      lazyComponent._status = Rejected;
      lazyComponent._result = error;
    }
  },
);

This will also require some updates to the docs.

Let me know your thoughts before I start...

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

react@16.7.0, Chrome 71, macOS 10.14

cc @acdlite @gaearon

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions