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>);
@UladzKha
Copy link

@karpolan many thanks!

@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.

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