Connecting to a Shared Web Worker
Utilize useSyncExternalStore to manage and synchronize state across multiple tabs with a shared Web Worker.
// shared-worker.js - The Shared Web Worker file
const connections = [];
let state = {};
self.onconnect = function(event) {
const port = event.ports[0];
connections.push(port);
port.onmessage = function(event) {
if (event.data.type === 'SET_STATE') {
state = { ...state, ...event.data.payload };
connections.forEach(p => p.postMessage({ type: 'STATE_UPDATED', state }));
}
};
port.start();
};
This is the shared worker (shared-worker.js) that handles connections and manages state. It listens for incoming messages to update the state and broadcasts the updated state to all connected tabs.
// main.js - Your client-side code to connect to the Shared Web Worker
import { useSyncExternalStore } from 'react';
const worker = new SharedWorker('shared-worker.js');
const subscribe = (callback) => {
worker.port.onmessage = (event) => {
if (event.data.type === 'STATE_UPDATED') {
callback();
}
};
worker.port.start();
return () => (worker.port.onmessage = null);
};
const getSnapshot = () => worker.port.state;
const useSharedWorkerState = () => useSyncExternalStore(subscribe, getSnapshot);
export default useSharedWorkerState;
This code creates a connection to the shared worker and sets up a function to use React's useSyncExternalStore to manage state synchronization.
// In your React component
import useSharedWorkerState from './main'; // Assume main.js is in the same directory
const MyComponent = () => {
const state = useSharedWorkerState();
// Your component logic... to update worker state
worker.port.postMessage({ type: 'SET_STATE', payload: { /* New State Here */ } });
return (
<div>
{/* Render your component using the state from the worker */}
</div>
);
};
export default MyComponent;
Example of a React component using the custom hook useSharedWorkerState to get shared state and send updates back to the worker.