Можем ли мы установить состояние компонента react в рабочем потоке?

#reactjs #react-hooks #web-worker

#reactjs #реагирующие хуки #веб-рабочий

Вопрос:

В react / nextjs мы можем установить состояние функционального компонента внутри рабочего потока. например

 //main.ts
export function myComponent (){
 const [user ,setUserDetails] = useState(false)
 const [profile ,setProfile] = useState(false)
....

  useEffect( () => {
   worker = new Worker('my.ts');
   worker.postMessage([user,profile,setUserDetails,setProfile])
  },[])
}
 

а затем в рабочем потоке

 /* my.js* /

self.onmessage = (data)=>{

    //long task
    users = getUSers();

   // this valid?
   data.setUserDetails(user);

   // continue process 
   profile = getProfile();

  data.setProfile(profile);

//and so on

}

 

Возможно ли это, поскольку мы не можем напрямую обновлять dom в worker, но я думаю, что react использует виртуальный dom.Так что это все еще возможно.Если нет, то как обойти это?

Ответ №1:

Да, это возможно. Простой способ добиться этого — использовать обратные вызовы в Comlink. Например, в вашем worker.js вы можете

 import * as Comlink from "comlink";

async function longTask(callback) {
  // get your users 
  await callback(users);
}

Comlink.expose(longTask);
 

и в вашем компоненте вы можете:

 import * as Comlink from "comlink";
import Worker from "worker-loader!./Worker.js";

const longTask = Comlink.wrap(new Worker());

const Component = () => {

    const [users, setUsers] = useState(null);

    const callback = (value) => {
        setUsers(value);
    };

    const onSomeEvent = async () => {
        await longTask(Comlink.proxy(callback));
    };
 
    // ...
 

Комментарии:

1. может ли это работать с компонентом на основе классов? Я начинаю понимать this.setState ... cannot be cloned