我有一个带有状态变量jobs的React组件。当状态变量ready为真时,它应该开始由Web Worker执行作业(一次执行一个)。
import React, { useEffect, useRef } from 'react'
// create webworker
const job_worker = new Worker("worker.bundle.js", { type: "module" });
function App() {
const [jobs, set_jobs] = React.useState([
{ ... },
{ ... },
])
const [ready, set_ready] = React.useState(false)
// start worker loop
useEffect(() => {
const worker_loop = async () => {
setTimeout(async () => {
// check if ready to execute a job
if (ready) { // <== suffers from 'stale closure'
// grab a job
const job = jobsRef.current.find(j => !j.done)
// listen for webworker results
job_worker.onmessage = (e) => {
console.log("received response from webworker: '", e.data, "'")
// SET RESULT IN JOB
// job is handled by worker; now start the worker_loop again
return worker_loop()
}
// post job to worker
job_worker.postMessage({job: job})
return // do not continue; 'onmessage' will continue the loop
}
return worker_loop()
}, 1000)
}
// start worker_loop
worker_loop()
}, [])
return (
<div>
{/* code to add jobs and set ready state */}
</div>
);
}我尝试使用一个(无限的) worker_loop,它在React组件挂载(使用useEffect)时启动。循环有点正常,但worker_loop中的ready变量保持在初始状态值(称为“陈旧闭包”问题)。jobs状态变量可能也是如此。
我已经尝试按照建议的here使用'createRef‘了。但问题依然存在。此外,我觉得有一个更简单的解决方案。
有没有更好的方法来处理React-state变量中的“作业”?可以访问React组件的某种“作业运行器进程/函数”。顺便说一下,我没有义务使用WebWorker。
发布于 2021-08-10 12:00:30
谢谢你的评论!
在React之外控制工作确实更有意义。我用@hookstate/core创建了一个全局状态,解决了这个问题。这使得在React之外访问和控制状态成为可能。更干净的代码!
https://stackoverflow.com/questions/68717086
复制相似问题