Created
August 21, 2020 10:49
-
-
Save msociety/71dd2ccd2c25118571893875a363d8e2 to your computer and use it in GitHub Desktop.
web worker
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 { cookData } from './helpers/someFunction'; | |
onmessage = ({ data: [...args] }) => { | |
const cookedData = cookData(...args); | |
postMessage(cookedData); | |
}; | |
// ---------- ComponentX.js ------------ | |
import React, { useMemo } from 'react'; | |
... | |
/* eslint-disable-next-line import/no-webpack-loader-syntax */ | |
import CookDataWorker from 'worker-loader!./cookData.worker'; | |
const cookDataWorker = new CookDataWorker(); | |
const ComponentX = () => { | |
... | |
const workerInput = useMemo(() => [arg1, arg2], [arg1, arg2]); | |
const { result: cookedData } = useWorker(cookDataWorker, workerInput); | |
... | |
// ---------- useWorker.js ------------ | |
import { useEffect, useRef, useReducer } from 'react'; | |
// * This hook is based in react-hooks-worker's useWorker | |
const defaultState = { result: null, error: null }; | |
const reducer = (state, { type, payload }) => { | |
switch (type) { | |
case 'reset': | |
return defaultState; | |
case 'message': | |
return { result: payload, error: null }; | |
case 'error': | |
return { result: null, error: 'error' }; | |
case 'messageerror': | |
return { result: null, error: 'messageerror' }; | |
default: | |
throw new Error('no such action type'); | |
} | |
}; | |
/** | |
* @param worker: instanceof Worker | |
*/ | |
const useWorker = (worker, input) => { | |
const [state, dispatch] = useReducer(reducer, defaultState); | |
const prevWorker = useRef(null); | |
useEffect(() => { | |
prevWorker.current = worker; | |
let dispatchSafe = action => dispatch(action); | |
/* eslint-disable no-param-reassign */ | |
worker.onmessage = e => dispatchSafe({ type: 'message', payload: e.data }); | |
worker.onerror = () => dispatchSafe({ type: 'error' }); | |
worker.onmessageerror = () => dispatchSafe({ type: 'messageerror' }); | |
/* eslint-enable no-param-reassign */ | |
return () => { | |
dispatchSafe = () => null; | |
worker.terminate(); | |
dispatch({ type: 'reset' }); | |
}; | |
}, [worker]); | |
useEffect(() => { | |
prevWorker.current.postMessage(input); | |
}, [input]); | |
return state; | |
}; | |
export default useWorker; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment