Skip to content

Instantly share code, notes, and snippets.

@Psvensso
Last active April 21, 2020 08:25
Show Gist options
  • Save Psvensso/12aa85d7611405144ac6d221625a77e6 to your computer and use it in GitHub Desktop.
Save Psvensso/12aa85d7611405144ac6d221625a77e6 to your computer and use it in GitHub Desktop.
React Serviceworker
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 }}>
import React from "react";
export const ServiceWorkerContext = React.createContext<{
installedUpdate: boolean;
waitingWorker: ServiceWorker | null;
}>({
installedUpdate: false,
waitingWorker: null,
});
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.
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