Skip to content

Instantly share code, notes, and snippets.

@karpolan
Created August 10, 2019 10:46
Show Gist options
  • Save karpolan/80cf28cb742851fcb3abb7796c4f7fdc to your computer and use it in GitHub Desktop.
Save karpolan/80cf28cb742851fcb3abb7796c4f7fdc to your computer and use it in GitHub Desktop.
withSuspense() HOC for React.lazy() + React.Suspense
import React from 'react';
import { CircularProgress, LinearProgress } from '@material-ui/core/';
/**
* Wraps the React Component with React.Suspense and FallbackComponent while loading.
* @param {React.Component} WrappedComponent - lazy loading component to wrap.
* @param {React.Component} FallbackComponent - component to show while the WrappedComponent is loading.
*/
export const withSuspense = (WrappedComponent, FallbackComponent = null) => {
return class extends React.Component {
render() {
if (!FallbackComponent) FallbackComponent = <LinearProgress />; // by default
return (
<React.Suspense fallback={FallbackComponent}>
<WrappedComponent {...this.props} />
</React.Suspense>
);
}
};
};
...
// Usage
const lazySomeComponent = React.lazy(() => import('./xxx/SomeComponent'));
export const SomeComponent = withSuspense(lazySomeComponent);
export const SomeComponentWithCircularProgress = withSuspense(lazySomeComponent, <CircularProgress />);
export const SomeComponentWithDiv = withSuspense(lazySomeComponent, <div>Loading...</div>);
@mz8i
Copy link

mz8i commented Jul 23, 2023

Nice! A comment on the naming - the argument you pass to Suspense's fallback prop is not actually a React component - it's a tree of React elements, in TS typed as ReactNode. So the naming FallbackComponent (capitalised, with "Component") is actually misleading - note you never write <FallbackComponent />. A better name for the second argument of the HOC would be simply fallback, or fallbackElement.

@Lazeta
Copy link

Lazeta commented Dec 25, 2024

or for functional component :


import React from 'react';
import { CircularProgress, LinearProgress } from '@material-ui/core/';

/**

  • Wraps the React Component with React.Suspense and FallbackComponent while loading.
  • @param {React.Component} WrappedComponent - lazy loading component to wrap.
  • @param {React.Component} FallbackComponent - component to show while the WrappedComponent is loading.
    */
    const withSuspense = (WrappedComponent, FallbackComponent = ) => {
    return (props) => (
    <React.Suspense fallback={FallbackComponent}>
    <WrappedComponent {...props} />
    </React.Suspense>
    );
    };

// Usage
const lazySomeComponent = React.lazy(() => import('./xxx/SomeComponent'));

export const SomeComponent = withSuspense(lazySomeComponent);
export const SomeComponentWithCircularProgress = withSuspense(lazySomeComponent, );
export const SomeComponentWithDiv = withSuspense(lazySomeComponent,

Loading...
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment