Last active
April 21, 2020 08:25
-
-
Save Psvensso/12aa85d7611405144ac6d221625a77e6 to your computer and use it in GitHub Desktop.
React Serviceworker
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
Somewhere in the app, use useServiceWorker ONCE! | |
And inject the result in the service worker. | |
const { installedUpdate, waitingWorker } = useServiceWorker( | |
"/<your path to generated SW>/service-worker.js" | |
); | |
<ServiceWorkerContext.Provider value={{ installedUpdate, waitingWorker }}> |
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 React from "react"; | |
export const ServiceWorkerContext = React.createContext<{ | |
installedUpdate: boolean; | |
waitingWorker: ServiceWorker | null; | |
}>({ | |
installedUpdate: false, | |
waitingWorker: null, | |
}); |
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
Somewhere in the app | |
export const PopupModal = () => { | |
const { installedUpdate, waitingWorker } = useContext(ServiceWorkerContext); | |
const [showPopup, setShowPopup] = useState(installedUpdate); | |
console.log(showPopup, installedUpdate, waitingWorker); | |
const doReload = useCallback(() => { | |
console.log("Reloading"); | |
if (waitingWorker) { | |
waitingWorker.postMessage({ type: "SKIP_WAITING" }); | |
} | |
setShowPopup(false); | |
setTimeout(() => { | |
window.location.reload(true); | |
}, 500); | |
}, [installedUpdate, waitingWorker]); | |
//We auto popup the warning here. | |
useEffect(() => { | |
if (installedUpdate) { | |
setShowPopup(true); | |
} | |
}, [installedUpdate]); | |
if (installedUpdate === true || waitingWorker) { | |
//Show the new version icon | |
if(installedUpdate){ | |
//show the modal | |
} | |
} | |
... | |
//Show warning icon if waiting worker, on Click we show a warning modal. If installed change we auto popup the modal. |
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 { useEffect, useState } from "react"; | |
export const useServiceWorker = (scriptPath: string) => { | |
const [installedUpdate, setInstalledUpdate] = useState<boolean>(false); | |
const [waitingWorker, setWaitingWorker] = useState<ServiceWorker | null>( | |
null | |
); | |
const onSWUpdate = (_: Event) => { | |
setInstalledUpdate(true); | |
}; | |
useEffect(() => { | |
if ("serviceWorker" in navigator) { | |
/** When we register a new service worker it compares the current one with the one we install */ | |
navigator.serviceWorker | |
.register(scriptPath) | |
.then((registration: ServiceWorkerRegistration) => { | |
/** After install we get the registered service worker, | |
* the "waiting" property shows if the service worker is "Waiting to be installed", | |
* meaning that we have been not been installed, the user has not accepted a refresh. | |
* If the user reloads the page it will be automatically installed. | |
*/ | |
registration.onupdatefound = onSWUpdate; | |
if (!!registration.waiting) { | |
setWaitingWorker(registration.waiting); | |
} | |
}); | |
} | |
}, [scriptPath]); | |
return { installedUpdate, waitingWorker }; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment