Loading

Lazy Loading with React Suspense

Lazy Loading with React Suspense

React.Suspense, along with React.lazy() the method was introduced with React v16.6 that allows us to load components asynchronously which means they are only loading the code behind them when they are really required when they are being rendered. This new ability makes code splitting and lazy loading of React components. And let's have a look at how this works now.

Getting Started

Before started, you will need to make sure you are using React v16.6 or higher. If you’re starting a fresh project, or if you’re working with an older project that is not on the correct version, simply check your package.json file:

"dependencies": {
    "react": "^16.6.0",
    "react-dom": "^16.6.0",
    "react-router-dom": "^4.3.1",
    "react-scripts": "2.0.5"
}

or install via npm or yarn package manager

$ npm install -s react react-dom
$ yarn add react react-dom

Then to handle lazy loading components, we have to import Suspene and lazy:

import React, { lazy, Suspense } from 'react';

React.lazy

The lazy() method 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.

Before

import SomeComponent from './SomeComponent';

After

const SomeComponent = lazy(() => import('./SomeComponent');

React.Suspense

The React.Suspense component allows us to wrap a component up and specify a fallback component which will be shown while the wrapped component loads:

<Suspense fallback={<div>Loading...</div>}>
  <SomeComponent />
</Suspense>

Make it All Together

Let’s start with the component we’re going to import. For this example, I’ve created a very simple components Posts.jsx and Users.jsx


import React from 'react';
const posts = props => (
  <div>This is post Page</div>
);
export default posts;

import React from 'react';
const user = props => (
  <div>This is user page</div>
);
export default user;

Next, we have to change out App.jsx boilerplate code and a small bit of state logic so that we can manually trigger the loading of our component:

import React, { Component, Suspense, Fragment } from 'react';

import User from './components/User';
const Posts = React.lazy(() => import('./components/Posts'));

class App extends Component {
  state = { showPosts: false };

  modeHandler = () => {
    this.setState(prevState => {
      return { showPosts: !prevState.showPosts };
    });
  };

  render() {
    return (
      <Fragment>
        <button onClick={this.modeHandler}>Toggle Mode</button>
        {this.state.showPosts ? (
          <Suspense fallback={<div>Loading...</div>}>
            <Posts />
          </Suspense>
        ) : (
          <User />
        )}
      </Fragment>
    );
  }
}

export default App;

Conclusion

Async rendering and that is really something useful and a great addition with React v16.6 we'll see more on that async rendering thing in future versions. And right now this is what we can use React lazy. Please be aware that this will not work if you're trying to serve a side rendered (SSR). We can see what's special when we reload the page and then go to the Network tab. Now after reloading clear it and now click on the posting page and you will see that there is loaded a new file and that is the file holding the code for this component and that is async rendering.

You may also like: How to update the state based on the previous state

Related Articles