Desmontar componentes y limpiar efectos
Desmontar significa retirar un componente de la interfaz. Un efecto que abre una conexión, inicia un intervalo o registra un evento debe ofrecer una forma de deshacer esa preparación.
Un reloj que se puede mostrar y ocultar #
1import { useEffect, useState } from 'react'; 2 3interface Props { 4 initialValue?: number; 5} 6 7function Reloj({ initialValue = 0 }: Props) { 8 const [second, setSecond] = useState(initialValue); 9 10 useEffect(() => { 11 const interval = window.setInterval(() => { 12 setSecond((prev) => prev + 1); 13 }, 1000); 14 console.log('Temporizador iniciado'); 15 16 return () => { 17 window.clearInterval(interval); 18 console.log('Temporizador detenido'); 19 }; 20 }, []); 21 22 return <p>Segundos: {second}</p>; 23} 24 25export default function Ejem_14() { 26 const [visible, setVisible] = useState(true); 27 return ( 28 <> 29 <button onClick={() => setVisible((prev) => !prev)}> 30 Mostrar u ocultar reloj 31 </button> 32 {visible && <Reloj />} 33 </> 34 ); 35}
setInterval programa una llamada aproximadamente cada segundo. Guarda su identificador para poder cancelarlo. La función que devuelve el efecto es la limpieza; React la invoca al desmontar esta instancia.
Usamos setSecond((prev) => prev + 1) para leer el estado pendiente. Si el callback capturara second del primer render con setSecond(second + 1), repetiría ese cálculo inicial en lugar de acumular segundos correctamente.
Preparación y limpieza deben encajar #
Con StrictMode, puedes observar iniciar, detener e iniciar durante las comprobaciones de desarrollo. Una limpieza correcta deja un único intervalo activo. No desactives las comprobaciones para ocultar la falta de limpieza.
Si un efecto dependiera de una prop, la limpieza anterior también se ejecutaría antes de preparar el efecto con el nuevo valor.
Comprueba el desmontaje #
Oculta el reloj y comprueba que aparece el mensaje de limpieza. Al mostrarlo de nuevo empieza desde su valor inicial: es una instancia nueva. Que un componente deje de verse mediante CSS no implica que se haya desmontado; en este ejemplo lo retiramos mediante la condición JSX.
El intervalo es una práctica de estado, no un cronómetro preciso: las pestañas en segundo plano y la carga del navegador pueden retrasar sus callbacks.
Cuestionario del tema #
Abre el cuestionario en las actividades de este tema para comprobar lo aprendido. Cada respuesta incluye una explicación.