Por lo general, veo este tipo de actualización de estado (esto es solo un ejemplo):
const NumArray = () => { const [numbers, setNumbers] = useState([]) return ( <div> <p>Numbers:[ {numbers} ]</p> ///////////////////// <button onClick={() => setNumbers(prevState => [...prevState, 1])}> ///////////////////// Click me </button> </div> ) }Pero si uso esta variación, todavía funciona:
const NumArray = () => { const [numbers, setNumbers] = useState([]) return ( <div> <p>Numbers:[ {numbers} ]</p> ///////////////////// <button onClick={() => setNumbers([...numbers, 1])}> ///////////////////// Click me </button> </div> ) }Mi pregunta es, ¿cuál es la diferencia entre las dos actualizaciones de estado? ¿Por qué la gente tiende a usar el que tiene la devolución de llamada?
useState es asíncrono. No actualiza el estado inmediatamente, pero tiene una cola que se usa para actualizar el objeto de estado. Esto se hace para mejorar el rendimiento de la representación de los componentes de React.
Aunque es asíncrona, la función useState no devuelve promesa. Por lo tanto, no podemos adjuntarle un controlador then o usar async/await para obtener los valores de estado actualizados. Y si tenemos algunas variables de estado que deben actualizarse de acuerdo con otra variable de estado, no podemos confiar en la variable de estado actualizada sincrónicamente.
La actualización de estado generalmente ocurre en el siguiente renderizado, pero incluso eso puede variar. Las actualizaciones por lotes dependen de la reacción, y no hay nada que podamos hacer para cambiar eso.
Así que escribiéndolo así:
<button onClick={() => setNumbers(prevState => [...prevState, 1])}> garantiza que prevState es en realidad un estado anterior. Mientras que al escribirlo sin devolución de llamada, no nos importa mucho si es el estado anterior exacto o no.