Last active
July 30, 2024 08:46
-
-
Save raphael-leger/4d703dea6c845788ff9eb36142374bdb to your computer and use it in GitHub Desktop.
React LazyWithRetry
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { lazy } from 'react'; | |
const lazyWithRetry = (componentImport) => | |
lazy(async () => { | |
const pageHasAlreadyBeenForceRefreshed = JSON.parse( | |
window.localStorage.getItem( | |
'page-has-been-force-refreshed' | |
) || 'false' | |
); | |
try { | |
const component = await componentImport(); | |
window.localStorage.setItem( | |
'page-has-been-force-refreshed', | |
'false' | |
); | |
return component; | |
} catch (error) { | |
if (!pageHasAlreadyBeenForceRefreshed) { | |
// Assuming that the user is not on the latest version of the application. | |
// Let's refresh the page immediately. | |
window.localStorage.setItem( | |
'page-has-been-force-refreshed', | |
'true' | |
); | |
return window.location.reload(); | |
} | |
// The page has already been reloaded | |
// Assuming that user is already using the latest version of the application. | |
// Let's let the application crash and raise the error. | |
throw error; | |
} | |
}); |
Note
For who needs a fully-tested TypeScript implementation for this, I created a package react-safe-lazy for out-of-the-box usage.
To install:
npm i react-safe-lazy
Then just replace React.lazy
with safeLazy
and you are good to go.
import { safeLazy } from 'react-safe-lazy';
const MyComponent = safeLazy(() => import('./MyComponent'));
You can also customize the retries and reloads:
import { createSafeLazy } from 'react-safe-lazy';
const safeLazy = createSafeLazy({
importRetries: 2,
forceReload: {
maxRetries: 1,
},
});
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for the code! But I think there is a little error.
In this part of code, if 'page-has-been-forced-to-refresh-by-component-loader' not exists you assign "false", and after that you use
pageHasAlreadyBeenForcedToRefresh
as condition, but!"false"
is false.Correction:
Then I think
hasToResolveComponentLoaderPromise
should be