-
-
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
nullwith<LinearProgress />in...withSuspense = (WrappedComponent, FallbackComponent = <LinearProgress />) => ....and you can get rid of check if its null
if (!FallbackComponent) FallbackComponent = <LinearProgress />; // by default