Tengo el siguiente código en React. Este código utiliza una función costosa en tiempo que realiza algunos cálculos sobre una gran cantidad de datos. al principio, el estado se llena con una matriz que dice que no hay cálculos. Cuando se presiona el botón, quiero que esa matriz del estado se llene con espera, y después de que se complete cada iteración sobre i, el elemento en la poción i se 'Listo'. El problema es que al usar el tiempo de espera establecido, los elementos DOM no se actualizan hasta que finaliza toda la función. Ignore los cálculos en for, no tienen sentido en este ejemplo. Para tener una idea, la función realiza un ajuste polinomial sobre los datos dados. Mi problema es cómo puedo actualizar los elementos Dom mientras la función se está ejecutando, así puedo saber qué datos se realizan y cuáles se están computando en tiempo real.
const Component = ( {data1, data2} ) => { const [state, setState] = useState(Array(data1.length).fill('No Computations')) const timeExpensiveFunction = () => { // data1.length = 10 let variable0 let variable1 let variable2 let variable3 for(let i = 0; i< data1.length; i++){ //data1[i].length = 40 000 for(let j = 0; j< data1[i].length; j++){ variable1 += data1[i][j] variable2 += variable1*data2[i][j]**3 variable3 += data2[i][j]**2 variable1 += data1[i][j]*data2[i][j] } setTimeout(() => { setState(state => { return[ ...state.slice(0,i), 'Done', ...state.slice(i+1), ] }) },1000) } return([variable1,variable2,variable3,variable4]) } const randomFunc = (e) => { setTimeout((e) => setState(Array(data1.length).fill('Waiting ...')),1000) timeExpensiveFunction() //Duration depends on the number of data, it is usually higher that 10-15 seconds } return ( <div> <div> {state.map((element) => ( {element} //This does not update with the function setTimeout. It sets after the expensive computation is over ))} </div> <div> <button onClick = {(e) => randomFunc(e)}>press</button> </div> </div> ) }En primer lugar, debe usar useState y useEffect para establecer un estado y volver a representar el DOM. Puedes usar como a continuación:
import { useState, useEffect } from 'react' const Component = () => { const [state, setState] = useState([1,2,3,4,5,6,7,8,9,10]) const [isPress, setPress] = useState(false); // use it to not call a method on first render const timeExpensiveFunction = () => { // lot of work here } const randomFunc = (e) => { setState([10,9,8,7,6,5,4,3,2,1]) setPress(true) } useEffect({ if (isPress) setTimeout(() => timeExpensiveFunction(),1000) }, [state]) return ( <div> <div> {state.map((element) => ( {element} ))} </div> <div> <button onClick = {(e) => randomFunc(e)}>press</button> </div> </div> ) }