Skip to content

Instantly share code, notes, and snippets.

@xsephiroth
Last active February 19, 2020 07:31
Show Gist options
  • Save xsephiroth/33d0c30aeca26afd89e454ec9604b9dd to your computer and use it in GitHub Desktop.
Save xsephiroth/33d0c30aeca26afd89e454ec9604b9dd to your computer and use it in GitHub Desktop.
React CRA service worker update demo
// setup check service worker manually update interval
const useUpdatePwaServiceWorker = (interval=60 * 1000) => {
useEffect(() => {
const update = () => {
const sw = window.navigator.serviceWorker;
sw && sw.getRegistrations()
.then(rs => rs.forEach(r => r.update()))
.catch(console.error);
};
setInterval(() => update(), interval);
}, []);
};
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
// Setup onUpdate config
/* Check 'src/serviceWorker.js'
// Execute callback
if (config && config.onUpdate) {
config.onUpdate(registration);
}
*/
serviceWorker.register({
onUpdate: registration => {
console.log(registration);
// Check waiting is not null
if (registration.waiting) {
/*
Send message to './build/service-worker.js',
emit service worker update immediately
---
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
---
*/
registration.waiting.postMessage({ type: 'SKIP_WAITING' });
// Listen 'statechange' event refresh the page content,
// after service worker updated
registration.waiting.addEventListener('statechange', e => {
if (e.target.state === 'activated') {
// Show some message to user,
// let the user decida when to refresh
window.location.reload();
}
})
}
}
});
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
interface ServiceWorkerStateChangeEventTarget extends EventTarget {
state: ServiceWorkerState;
}
serviceWorker.register({
onUpdate: registration => {
const sw: ServiceWorker | null = registration.waiting;
// listen new service worker actived, reload page
sw?.addEventListener('statechange', e => {
const state = (e?.target as ServiceWorkerStateChangeEventTarget).state;
state === 'activated' && window.location.reload();
})
// send message to current service worker active new worker
sw?.postMessage({ type: 'SKIP_WAITING' });
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment