Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to lazy load multiple components at a same time

I have 2 components, I want to load all of them using lazy load something like

const A = lazy(() => import("../test/A")); 
const B = lazy(() => import("../test/B")); 

This will create 2 separate bundles, and will import them when required.

But, I want to create a single bundle and when that bundle loads I should be able to use both above components.

I also don't want to create a single component containing both the above components as I want a separate route for both of them

I tried to do something like this https://codesandbox.io/s/eager-raman-mdqzc?file=/src/App.js

Can please somebody will explain me Is this type of functionality possible, If yes then how and what am I doing wrong

like image 650
Adarsh Avatar asked Apr 27 '20 17:04

Adarsh


People also ask

What is lazy loading and how to use it?

Lazy loading can be applied to different levels of your application-development process, from modules to components. Module-level lazy loading is quite famous in the Angular world, but component-level lazy loading is something less spoken about.

How to implement lazy loading in react?

We can now implement lazy loading by making use of React.lazy (): Note: React.lazy () used this way returns a Promise object. That promise resolves to a module that contains a React component we want to lazy load in its default export.

How do I lazy load a component in another component?

You can lazily load a component in any other component, hence creating a parent-child relationship between them. You want to lazy load GreetComponent on the click of the button in the parent component, so to do that add a button as shown next.

How to lazy load a component in angular?

This article explains various ways of lazy loading a component in Angular, including via an import statement inside an async-await function and via the then method. The previous major version of Angular, 9, came with a lot of amazing features, and one of the most talked-about among them is the Ivy renderer. Ivy is a new compiler of Angular.


2 Answers

There are probably some tuning options in the code splitter that might better accomplish what you are trying to achieve. But if you don't want to mess around with those (or they are not available to change because you are using a preset configuration), then perhaps you can combine the modules into a single file, and lazy load that "combo module".

To do that, we first need to know how lazy determines what component in a module to load, and what types of objects it expects. From the docs:

The React.lazy function lets you render a dynamic import as a regular component.

React.lazy takes a function that must call a dynamic import(). This must return a Promise which resolves to a module with a default export containing a React component.

The lazy component should then be rendered inside a Suspense component, which allows us to show some fallback content (such as a loading indicator) while we’re waiting for the lazy component to load.

You can place the Suspense component anywhere above the lazy component. You can even wrap multiple lazy components with a single Suspense component.

So according to that, if you want to use lazy() to wrap the module, then you have to have a component as the default property of the module. So it won't allow you to automatically use a module that uses named exports as a component. However, you can easily make a promise that transforms a named export to a default export, and wrap that in lazy:

// in comboModule.js:
export A from '../test/A'
export B from '../test/B'

// in the code that needs lazy modules
  const A = lazy(() => import('./comboModule').then((module) => ({default: module.A})))
  const B = lazy(() => import('./comboModule').then((module) => ({default: module.B})))

Note that we have to call import inside the initializer function passed to lazy, or the import will start immediately. Part of lazy's benefit is that is lets you wait until the parent component renders the lazy component before loading. However, import() should cache the result from the first import, and only load the code once.

In the initializer function, we use then to transform the result of import() from something like Promise({A: <Component>, B: <Component>}) to what lazy expects from the initializer function: Promise({default: <Component>})

Now we have two lazy components that both source from one module file.

Resources:

  • React code splitting
  • import/export
  • Promise.prototype.then (then returns a promise)
like image 84
Garrett Motzner Avatar answered Oct 31 '22 23:10

Garrett Motzner


You can use Suspense for waiting both of them. There are two bundles, but you can wait of loading both of them

import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Switch>
        <Route exact path="/" component={Home}/>
        <Route path="/about" component={About}/>
      </Switch>
    </Suspense>
  </Router>
);
like image 33
IT's Bruise Avatar answered Oct 31 '22 22:10

IT's Bruise