Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

353
Views
¿Por qué useState hook no se actualiza mientras se usa loop dentro de useEffect()?

Caso 1:

 const [present, setPresent] = useState([]); useEffect(() => { for (var j = 1; j <= totalPeriod; j++) { setPresent([ ...present, { period: j, present: true, }, ]); } }, []);

Caso 2:

 const [present, setPresent] = useState([]); let createPresent = []; for (var j = 1; j <= totalPeriod; j++) { createPresent = [ ...createPresent, { period: j, present: true, }, ] } useEffect(() => { setPresent(createPresent); }, []);

Cuando trato de actualizar el estado actual usando el bucle dentro de useEffect() en el Caso 1, el estado actual no se actualiza. Pero cuando uso el bucle por separado fuera de useEffect() y creo una matriz que luego asigno al estado actual en el caso 2, el estado actual se actualiza.

Cuál es la razón detrás de esto? ¿Por qué el estado actual no se actualiza en el Caso 1?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

En el caso a continuación, su estado present no es el resultado de cada actualización de estado posterior, sino la inicial que tenía, que es [] . React agrupará estas actualizaciones por lotes y no hará que sucedan sincrónicamente, por lo que solo habrá una actualización de estado con la entrada present actualizada a la última entrada en su for loop .

 const [present, setPresent] = useState([]); useEffect(() => { for (var j = 1; j <= totalPeriod; j++) { setPresent([ ...present, { period: j, present: true, }, ]); } }, []);

En el caso a continuación, primero está ensamblando una matriz createPresent con todos los valores que necesita y finalmente llamando a la función de actualización de estado, es decir, setPresent para establecer el estado.

 const [present, setPresent] = useState([]); let createPresent = []; for (var j = 1; j <= totalPeriod; j++) { createPresent = [ ...createPresent, { period: j, present: true, }, ] } useEffect(() => { setPresent(createPresent); }, []);

Para lograr el segundo comportamiento con el primero, puede utilizar la devolución de llamada del actualizador de estado que contiene el estado anterior como argumento de la siguiente manera: -

 const [present, setPresent] = useState([]); useEffect(() => { for (let j = 1; j <= totalPeriod; j++) { setPresent(prevState=>[ ...prevState, { period: j, present: true, }, ]); } }, []);

Aquí también se procesa por lotes la actualización de estado, pero se tiene en cuenta el estado anterior antes de actualizar el siguiente.

Cuando digo una actualización de estado por lotes, quiero decir que solo habrá un solo renderizado. Puede verificarlo haciendo console.log('render') en el cuerpo de la función de su componente.

Tenga en cuenta el uso de let en lugar de var aquí, ya let tiene un alcance, obtendrá el valor exacto para la variable j .

over 4 years ago · Santiago Trujillo Report

0

La suposición que está haciendo en el Caso 1 es que la llamada setPresent es síncrona y que actualiza el present de inmediato, mientras que en realidad las actualizaciones de estado en React casi siempre son asíncronas. Por lo tanto, la variable present dentro for (var j = 1; j <= totalPeriod; j++) { será igual al valor original, que es una matriz vacía [] . Entonces, en esencia, estás configurando el estado para esto una y otra vez:

 [ ...[], { period: j, present: true, }, ]

Esto dará como resultado que su estado se actualice a la última matriz que crea el ciclo for . Entonces, si totalPeriod es igual a 5, su estado terminará siendo [{period: 5, present: true}] en lugar de [{period: 1, present: true}, {period: 2, present: true}, ... ]

En el Caso 2, todo es muy sencillo, ensambla la matriz sin alterar las variables de estado y luego establece el estado de una sola vez. Justo como se supone que debes hacerlo en este caso.

over 4 years ago · Santiago Trujillo Report

0

Además de otras respuestas:

Debe tener en cuenta algunos puntos clave mientras actualiza los estados en el componente React. En primer lugar, el estado de actualización en el estado React no es síncrono, por lo tanto, se procesará por lotes a menos que lo active de forma asíncrona.

 state = { count: 0}; increment() { this.setState({ count: this.state.count + 1}); this.setState({ count: this.state.count + 1}); this.setState({ count: this.state.count + 1}); console.log(this.state.count) // 0 } increment() console.log(this.state.count); // 1

Y, el valor final de this.state.count será 1 después de completar la llamada incemenent()

Debido a que React agrupa todas las llamadas, descubre el resultado y luego realiza ese cambio de manera eficiente. Una especie de código JavaScript puro, fusionándose donde gana el último

 newState = Object.assign( {}, firstSetStateCall, secondSetStateCall, thirdSetStateCall, );

Entonces, podemos decir aquí que todo tiene que ver con la fusión de objetos de JavaScript. Así que hay otra forma genial, en la que pasamos una función en setState en lugar de object.

En segundo lugar, en el caso de useState de ganchos de reacción, la updating function (segundo elemento de la matriz devuelta por useState()) no se vuelve a representar en el cambio de contenido del objeto de estado, la referencia del objeto de estado debe cambiarse. Por ejemplo: aquí creé sandbox: enlace

si no hubiera cambiado la referencia de la matriz (que es el estado), no volvería a representar los componentes.

 for (let key in newState) { newStateToBeSent[key] = newState[key]; // chnaging the reference }
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!