-
-
Save karpolan/80cf28cb742851fcb3abb7796c4f7fdc to your computer and use it in GitHub Desktop.
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>); |
Could be :)
@karpolan could you please help me ? Can I move import
logic into the HOC ? I mean to move const lazySomeComponent = React.lazt(() => import('path'));
into the withSuspense
method?
You can, but in that case you need await loading...
I suggest to use following way:
import React from 'react';
/**
* Note: Don't import/export all Views directly, use lazy loading!
*/
import { withSuspense } from '../components';
import NotFound from './NotFound';
/**
* Views/Pages with Lazy Loading
*/
const Welcome = withSuspense(React.lazy(() => import('./Welcome')));
const About = withSuspense(React.lazy(() => import('./About')));
const MyProfile = withSuspense(React.lazy(() => import('./MyProfile')));
export { NotFound, Welcome, MyProfile, About };
@karpolan many thanks!
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
.
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,
Hey, thanks for this!
I have small suggestion: you can replace
null
with<LinearProgress />
in...withSuspense = (WrappedComponent, FallbackComponent = <LinearProgress />) => ....
and you can get rid of check if its null
if (!FallbackComponent) FallbackComponent = <LinearProgress />; // by default