import React, { useState} from "react"; import ReactDOM from "react-dom"; function App() { const [count, setCount] = useState(0); function handleAlertClick(){ return (setTimeout(() => { alert("You clicked on: " + count); }, 3000)) } return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}>Click me</button> <button onClick={handleAlertClick}>Show alert</button> </div> ); }
¡Solo quiero saber si esto funciona de la manera que creo que funciona, o si hay una mejor explicación!
Cada vez que se llama al método setState
, el estado obtiene una nueva referencia. Esto significa que el estado original no tiene un valor nuevo, sino que creamos un estado nuevo con un valor nuevo. Cuando hacemos clic en el segundo botón, la función del controlador de eventos captura la referencia del estado original. Incluso si hacemos clic en el primer botón muchas veces, cuando se muestre la alerta, mostrará el valor del estado que el controlador de eventos capturó su referencia.
¿Es esto correcto?
La razón por la que la alert
muestra el valor obsoleto de count
se debe a que la devolución de llamada pasada a setTimeout
hace referencia a un valor obsoleto de count
capturado por el cierre . Esto generalmente se conoce como un cierre obsoleto .
En el renderizado inicial, la función anónima pasada como una devolución de llamada a setTimeout
captura el valor de count
como 0
, y cuando se hace clic en el botón show alert
la devolución de llamada se pone en cola pero con el valor obsoleto de count.
En el caso anterior, la solución más fácil para mostrar el valor actualizado de count en el mensaje de alerta y solucionar el problema de cierre obsoleto será usar una ref
.
function App() { const [count, setCount] = useState(0); const latestValue = useRef(count); const handleAlertClick = () => { setTimeout(() => { alert(`count is: ${latestValue.current}`); }, 3000); }; return ( <div> <p>You clicked {count} times</p> <button onClick={() => { setCount(prev => { latestValue.current = prev + 1; return prev + 1; }); }} > Click me </button> <button onClick={handleAlertClick}>Show alert</button> </div> ); }
Demostración de trabajo en codesandbox
Los ganchos dependen en gran medida de los cierres para funcionar, por lo que es muy probable que tenga problemas con los cierres obsoletos . Aquí hay un buen artículo sobre cómo los cierres obsoletos crean problemas cuando se usan ganchos de reacción y demuestra cómo solucionar algunos problemas en algunas situaciones.