Languages
[Edit]
EN

React - import component dynamically

13 points
Created by:
jarlh
635

In this short article, we would like to show how to import components dynamically in React.

Quick solution:

import React from 'react';

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

 

Custom component import logic

This section shows, how to create custom logic that loads indicated component when the first time is used.

That kind of component attaching can be useful when:

  • we don't want to load some parts until it are used,
  • component logic is located on a different server,
  • when we use Server-Side Rendering (SSR), the attached component uses BOM (Browser Object Model, like: window, location, navigator, etc.) and we want to avoid internal problems with undefined BOM objects in compilation with NodeJS (SSR in Gatsby/Preact has problems with JS libraries that calls window, location, nagator, etc.).

Note:
The below example shows how to create useComponent hook that let us to load component with async import - be sure that building tool is configured to compile separated bundle for that imports.

useComponent.jsx file:

import { useState } from 'react';

let componentPromise = null;
let componentModule = null;

// The method runs component importing.
//
const importComponent = () => {
    if (componentModule) {
        return Promise.resolve(componentModule);
    }
    if (componentPromise) {
        return componentPromise;
    }
    componentPromise = import('/path/to/my/component') // change it to something
        .then((module) => {
            componentModule = module;
            return module;
        });
    return componentPromise;
};

// Uncomment the below line to start module loading as soon as it possible.
//
// prepareComponent();

const useComponent = () => {
    const [component, setComponent] = useState(componentModule);
    if (component === undefined) {
        importComponent()
            .then(setComponent)    // we just wait until component is ready
            .catch(console.error); // we want to see loading exceptions in console
    }
    return component;
};

export default useComponent;

Usage example:

import React from 'react';
import useComponent from './useComponent';

const App = () => {
    const Component = useComponent();
    return (
      <div>
        {Component ? <Component.default /> : <span>Component is not imported yet!</span>}
      </div>
    );
};

export default App;

Note: change Component.default to proper export name if it is necessary.

Example import names:

static importdynamic import
import MyComponent from './my-component';const Component = useComponent();
const MyComponent = Component.default;
import {MyComponent1, MyComponent2}
from './my-component';

const Component = useComponent();
const MyComponent1 = Component.MyComponent1;
const MyComponent2 = Component.MyComponent2;

 

Universal component import logic

In this section, we would like to show how to modify the above logic to import different components with the same logic.

useComponent.jsx file:

import { useState } from 'react';

const statuses = { }; // keeps information about imported modules

// The method runs component importing.
//
export const importComponent = (id, execute) => {
    const status = statuses[id] ?? (statuses[id] = {});
    if (status.module) {
        return Promise.resolve(status.module);
    }
    if (status.promise) {
        return status.promise;
    }
    status.promise = execute()
        .then((module) => {
            status.module = module;
            return module;
        });
    return status.promise;
};

const useComponent = (id, execute) => {
    const [component, setComponent] = useState(() => {
        const status = statuses[id];
        return status ? status.module : undefined;
    });
    if (component === undefined) {
        importComponent(execute)
            .then(setComponent)    // we just wait until component is ready
            .catch(console.error); // we want to see loading exceptions in console
    }
    return component;
};

export default useComponent;

Usage example:

import React from 'react';
import useComponent, {importComponent} from './useComponent';

// Uncomment below line to start module loading as soon as it possible.
//
// importComponent('MyComponent', () => import('/path/to/my/component'));

const App = () => {
    const Component = useComponent('MyComponent', () => import('/path/to/my/component')); // change it to something
    return (
      <div>
        {Component ? <Component.default /> : <span>Component is not imported yet!</span>}
      </div>
    );
};

export default App;

Note:

Some building tools resolves import('/path/to/component/module') paths that makes impossible to use variables with imports, e.g. import(componentPath) - Webpack has that. This is reasone why we should call import() with string literal.

 

Alternative titles

  1. React - dynamic import for component
  2. React - import component asynchronous
  3. React - component async import
  4. React - load component dynamically
Donate to Dirask
Our content is created by volunteers - like Wikipedia. If you think, the things we do are good, donate us. Thanks!
Join to our subscribers to be up to date with content, news and offers.

ReactJS

React - import component dynamically
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join