Estoy tratando de llenar una matriz con varias matrices de objetos, pero en el primer renderizado, los valores se completan de manera inversa dentro de la matriz y, después de actualizar, vuelven a ser como deberían ser.
const getProducts = async (data) => { await productServices .getProductsByTakeoffWizardStep(data) .then((response) => { setRows((rows) => [...rows, response.data]); }) .catch((error) => { console.log(error.response); }); }; const getTakeoffIDs = () => { var i = 1; takeoffServices .getTakeoffSteps(5) .then((response) => { response.data.forEach((element) => { setSteps((steps) => [...steps, element.description]); setStepsID((stepsID) => [...stepsID, element.stepID]); var data = { StepID: element.stepID, TakeoffID: 4 }; getProducts(data); setStepSequence((stepSequence) => [ ...stepSequence, "Step " + i + "", ]); i = i + 1; }); }) .catch((error) => { console.log(error.response); }); }; useEffect(() => { setSteps([]); setStepsID([]); setRows([]); getTakeoffIDs(); }, []);Entonces, en el primer renderizado, la matriz se ve así
(2) [Array(1), Array(2)] 0: Array(1) 0: {product: {…}, quantity: null} length: 1 [[Prototype]]: Array(0) 1: Array(2) 0: {product: {…}, quantity: null} 1: {product: {…}, quantity: null} length: 2 [[Prototype]]: Array(0) length: 2 [[Prototype]]: Array(0)y después de actualizar la página se ve así
(2) [Array(2), Array(1)] 0: Array(2) 0: {product: {…}, quantity: null} 1: {product: {…}, quantity: null} length: 2 [[Prototype]]: Array(0) 1: Array(1) 0: {product: {…}, quantity: null} length: 1 [[Prototype]]: Array(0) length: 2 [[Prototype]]: Array(0)¿Qué podría estar causando esto y qué puedo hacer para solucionarlo?
Estoy accediendo a la página usando history.push() desde otra página, pero ninguno de los estados que paso afecta el proceso de recuperación, solo la visualización de algunos párrafos que no están relacionados con los datos que estoy obteniendo.
Así es como escribiría esto:
const getProduct = async (data) => { try { const response = await productServices.getProductsByTakeoffWizardStep(data); return response.data; } catch (error) { console.log(error.response); } } const getTakeoffIDs = () => { takeoffServices .getTakeoffSteps(5) .then(async (response) => { // try moving setSteps(), setStepsID() and setStepSequence() up here, so they don't wait for the products. const products = await Promise.all( response.data.map(element => getProduct({ StepID: element.stepID, TakeoffID: 4 })) ); setRows((rows) => [ ...rows, ...products ]); setSteps((steps) => [ ...steps, ...response.data.map(element => element.description) ]); setStepsID((stepsID) => [ ...stepsID, ...response.data.map(element => element.stepID) ]); setStepSequence((stepSequence) => [ ...stepSequence, ...response.data((_, i) => `Step ${i + 1}`) ]); }) .catch((error) => { console.log(error.response); }); }; useEffect(() => { setSteps([]); setStepsID([]); setRows([]); getTakeoffIDs(); }, []);setState() s varias veces, haría Array.map() los datos y los agregaría todos a la vez.await a que terminen todas las llamadas getProduct() y también enviarlas a la vez; en orden. Lo único de lo que no estoy seguro es si desea que setRows() se llame junto con el otro setter, o si los otros deberían ir primero (porque los datos están disponibles) y setRows() debería llamarse más tarde, tan pronto como los datos estén disponibles.