tutoriales·12 min de lectura

El Ciclo de Vida de React Explicado: De Mounting a Unmounting

Entiende como nacen, viven y mueren los componentes de React. Una guía visual e interactiva sobre mounting, updating y unmounting desde cero.

El Ciclo de Vida de React: De Mounting a Unmounting

El ciclo de vida de React determina qué pasa cuando un componente aparece en pantalla, se actualiza con nuevos datos, y finalmente desaparece. Entender mounting, updating y unmounting es fundamental para saber cuando cargar datos, cuando limpiar recursos y cuando actualizar la interfaz.

Si estos términos te suenan confusos, esta guía te los explica con ejemplos concretos y código que puedes probar directamente.

La analogia de la tienda fisica

Para entender el ciclo de vida, piensa en una tienda fisica. Cada día pasa por tres etapas:

1. Abrir la tienda (Mounting)

  • Llegas por la mañana
  • Prendes las luces
  • Organizas los productos
  • Abres la puerta al público

2. Operar durante el día (Updating)

  • Los clientes entran y salen
  • Reorganizas productos
  • Actualizas precios
  • Respondes preguntas

3. Cerrar la tienda (Unmounting)

  • Sacas a los últimos clientes
  • Apagas las luces
  • Guardas el dinero
  • Cierras con llave

Un componente de React funciona exactamente igual. Nace (mounting), vive y cambia (updating), y eventualmente muere (unmounting).

Por qué es importante?

Entender el ciclo de vida te ayuda a saber CUANDO hacer las cosas: cuando cargar datos, cuando limpiar recursos, cuando actualizar la pantalla. Es fundamental para escribir aplicaciones React que funcionen correctamente.

Las tres etapas del ciclo de vida

1. Mounting: Naciendo en la pantalla

Mounting es cuando tu componente aparece por primera vez en la pantalla.

Piensalo así: cuando un componente se "monta", React esta haciendo esto:

  1. Lee tu código del componente
  2. Ejecuta todo el código dentro del componente
  3. Crea los elementos HTML
  4. Los inserta en la página
  5. El usuario finalmente los ve

Ejemplo de la vida real:

Cuando abres Instagram, el componente del feed se monta:

  • React carga las publicaciones
  • Crea todos los elementos (imágenes, likes, comentarios)
  • Los muestra en tu pantalla
jsx
function Feed() {
  // Esto se ejecuta cuando el componente nace (se monta)
  console.log('El Feed acaba de nacer')
 
  return (
    <div>
      <h1>Tu Feed</h1>
      <Post />
      <Post />
      <Post />
    </div>
  )
}

El console.log se ejecuta una sola vez cuando el componente aparece por primera vez.

Visualizalo

Mounting es como cuando nace un bebe. Antes no existia, ahora existe. Antes la pantalla estaba vacia (o tenia otra cosa), ahora tu componente esta ahi.

2. Updating: Cambiando mientras vive

Updating es cuando tu componente ya existe en la pantalla pero algo cambia.

Volviendo a la tienda: durante el día cambias precios, reorganizas productos, pero la tienda sigue abierta. No la cierras y vuelves a abrir, solo haces ajustes.

Que causa un update en React?

Tres cosas principales:

a) Cambia el state (estado interno)

jsx
function Contador() {
  const [número, setNumero] = useState(0)
 
  // Cada vez que haces click, el componente se actualiza (re-renderiza)
  return (
    <div>
      <p>Contador: {número}</p>
      <button onClick={() => setNumero(número + 1)}>
        Sumar
      </button>
    </div>
  )
}

Cada click causa un update. El componente no nace de nuevo, solo se actualiza para mostrar el nuevo número.

b) Cambian las props (datos que recibe de afuera)

jsx
function SaludoPersonalizado({ nombre }) {
  // Si nombre cambia de "Ana" a "Carlos", esto se actualiza
  return <h1>Hola, {nombre}</h1>
}

Si el componente padre cambia el nombre que le pasa, este componente se actualiza.

c) El componente padre se actualiza

jsx
function Padre() {
  const [contador, setContador] = useState(0)
 
  return (
    <div>
      <button onClick={() => setContador(contador + 1)}>
        Incrementar
      </button>
      <Hijo /> {/* Este hijo se re-renderiza aunque no use el contador */}
    </div>
  )
}

Cuando el padre se actualiza, sus hijos también se actualizan (aunque hay formas de evitar esto).

Re-render no significa recrear todo

Cuando un componente se actualiza (re-renderiza), React NO borra todo y lo vuelve a crear. Solo actualiza lo que cambio. Es eficiente.

3. Unmounting: Desapareciendo de la pantalla

Unmounting es cuando tu componente se va, desaparece, deja de existir.

Es como cerrar la tienda al final del día. Ya no esta disponible, las luces se apagan, todo se limpia.

Cuando se desmonta un componente?

a) Cambias de página/ruta

jsx
// Estas en la página de inicio
<HomePage /> // Montado
 
// Navegas a perfil
<ProfilePage /> // HomePage se desmonta, ProfilePage se monta

b) Rendering condicional

jsx
function App() {
  const [mostrarModal, setMostrarModal] = useState(false)
 
  return (
    <div>
      <button onClick={() => setMostrarModal(true)}>
        Abrir Modal
      </button>
 
      {mostrarModal && <Modal />} {/* Se monta cuando mostrarModal es true */}
 
      <button onClick={() => setMostrarModal(false)}>
        Cerrar Modal
      </button>
      {/* Al cerrar, Modal se desmonta (desaparece) */}
    </div>
  )
}

c) El componente padre se desmonta

Si un componente desaparece, todos sus hijos también desaparecen.

por qué importa el unmounting?

Porque necesitas limpiar cosas cuando un componente se va:

  • Si abriste una conexión a WebSocket, cierrala
  • Si pusiste un timer, cancelalo
  • Si te suscribiste a eventos, desuscribete

Si no limpias, causas memory leaks (fugas de memoria) y tu aplicación se vuelve lenta.

useEffect: El hook del ciclo de vida

useEffect es la forma moderna de ejecutar código en momentos especificos del ciclo de vida.

Piensa en useEffect como instrucciones especiales que le das a React:

"Oye React, cuando este componente se monte (o cuando algo específico cambie), ejecuta este código. Y si hay que limpiar algo cuando se desmonte, aquí esta como hacerlo."

Estructura básica de useEffect

jsx
useEffect(() => {
  // código que se ejecuta después del mounting o updating
 
  return () => {
    // código de limpieza que se ejecuta en unmounting
  }
}, [dependencias])

Vamos a descomponerlo:

1. La función principal

jsx
useEffect(() => {
  console.log('Componente montado o actualizado')
})

Este código se ejecuta:

  • después del primer render (mounting)
  • después de cada update (re-render)

2. El array de dependencias

jsx
useEffect(() => {
  console.log('Solo cuando algo específico cambia')
}, [variable1, variable2])

Con el array de dependencias, el efecto solo se ejecuta cuando esas variables cambian.

3. La función de limpieza (cleanup)

jsx
useEffect(() => {
  console.log('Componente montado')
 
  return () => {
    console.log('Componente desmontado - limpiando')
  }
}, [])

La función que retornas se ejecuta justo antes de que el componente se desmonte.

Los tres patrones principales de useEffect

Patron 1: Solo en mounting (una sola vez)

El caso más común es cargar datos con Fetch API cuando el componente aparece por primera vez:

jsx
function PerfilUsuario() {
  const [usuario, setUsuario] = useState(null)
 
  // Array vacio [] = solo se ejecuta una vez al montar
  useEffect(() => {
    console.log('Cargando usuario...')
 
    fetch('/api/usuario')
      .then(res => res.json())
      .then(data => setUsuario(data))
  }, []) // Array vacio es clave aquí
 
  return <div>{usuario?.nombre}</div>
}

cuándo usar: Cargar datos iniciales, configurar cosas una sola vez.

Analogia de la tienda: Cosas que haces solo cuando abres por primera vez en el día (encender luces, abrir caja registradora).

Patron 2: En mounting y cuando algo cambia

Un ejemplo típico es un buscador que reacciona cada vez que el usuario escribe (si necesitas búsqueda del lado del cliente, revisa como implementarla con Fuse.js):

jsx
function BuscadorProductos() {
  const [búsqueda, setBusqueda] = useState('')
  const [resultados, setResultados] = useState([])
 
  // Se ejecuta cuando búsqueda cambia
  useEffect(() => {
    if (búsqueda.length > 0) {
      console.log('Buscando:', búsqueda)
 
      fetch(`/api/buscar?q=${búsqueda}`)
        .then(res => res.json())
        .then(data => setResultados(data))
    }
  }, [búsqueda]) // Se ejecuta cuando búsqueda cambia
 
  return (
    <div>
      <input
        value={búsqueda}
        onChange={(e) => setBusqueda(e.target.value)}
      />
      <ul>
        {resultados.map(r => <li key={r.id}>{r.nombre}</li>)}
      </ul>
    </div>
  )
}

cuándo usar: Reaccionar a cambios especificos (búsquedas, filtros, etc.).

Analogia de la tienda: Cada vez que llega un cliente nuevo (búsqueda cambia), le prestas atención (haces el fetch).

Patron 3: Con limpieza en unmounting

jsx
function RelojEnVivo() {
  const [hora, setHora] = useState(new Date())
 
  useEffect(() => {
    console.log('Iniciando reloj')
 
    // Actualizar la hora cada segundo
    const intervalo = setInterval(() => {
      setHora(new Date())
    }, 1000)
 
    // Limpieza: detener el intervalo cuando el componente se desmonte
    return () => {
      console.log('Deteniendo reloj')
      clearInterval(intervalo)
    }
  }, [])
 
  return <div>{hora.toLocaleTimeString()}</div>
}

cuándo usar: Timers, suscripciones, conexiones que necesitas cerrar.

Analogia de la tienda: Cuando cierras al final del día, apagas las luces (clearInterval). Si no lo haces, las luces quedan prendidas toda la noche gastando electricidad (memory leak).

Error común: olvidar la limpieza

Si creas un interval, timer, o suscripción en useEffect, SIEMPRE limpia en el return. Si no, ese código seguira ejecutandose incluso después de que el componente desaparezca.

Ejemplos visuales e interactivos

Demo 1: Mounting y Unmounting

Estado:No montado

¿Qué está pasando?

  • • Click en "Mostrar" → El componente se monta (nace)
  • • Click en "Ocultar" → El componente se desmonta (muere)
  • • Revisa la consola del navegador para ver los logs

Demo 1: Visualizando mounting y unmounting

Arriba puedes ver el componente interactivo en acción. aquí esta el código de cómo funciona:

plaintext
[Boton: Mostrar Componente]
 
Estado: No montado

Cuando haces click en "Mostrar Componente":

plaintext
Estado: Montando...
Estado: Montado
 
[Componente visible aquí]
 
[Boton: Ocultar Componente]

Cuando haces click en "Ocultar Componente":

plaintext
Estado: Desmontando...
Estado: Desmontado

código del demo:

jsx
function DemoMountingUnmounting() {
  const [mostrar, setMostrar] = useState(false)
 
  return (
    <div>
      <button onClick={() => setMostrar(!mostrar)}>
        {mostrar ? 'Ocultar' : 'Mostrar'} Componente
      </button>
 
      {mostrar && <ComponenteDemo />}
    </div>
  )
}
 
function ComponenteDemo() {
  useEffect(() => {
    console.log('Componente MONTADO')
 
    return () => {
      console.log('Componente DESMONTADO')
    }
  }, [])
 
  return (
    <div style={{ padding: '20px', background: '#e0f7fa', margin: '10px' }}>
      Hola! Estoy vivo en la pantalla
    </div>
  )
}

Pruebalo:

  1. Abre la consola del navegador (F12)
  2. Click en "Mostrar" - verás "Componente MONTADO"
  3. Click en "Ocultar" - verás "Componente DESMONTADO"

Demo 2: Visualizando updates (re-renders)

plaintext
Contador: 0
 
[Boton: +1]
 
Renders totales: 1

Cada vez que haces click:

plaintext
Contador: 1
Renders totales: 2
 
Contador: 2
Renders totales: 3

código del demo:

jsx
function ContadorConRenders() {
  const [contador, setContador] = useState(0)
  const renderCount = useRef(0)
 
  // Esto se ejecuta en cada render
  renderCount.current = renderCount.current + 1
 
  useEffect(() => {
    console.log(`Update: Contador ahora es ${contador}`)
  }, [contador])
 
  return (
    <div>
      <h2>Contador: {contador}</h2>
      <p>Renders totales: {renderCount.current}</p>
      <button onClick={() => setContador(contador + 1)}>
        +1
      </button>
    </div>
  )
}

Observa: Cada click causa un update (re-render), pero el componente no se desmonta ni se vuelve a montar.

Demo 2: Updates (Re-renders)

Contador
0
Renders totales
1

¿Qué está pasando?

  • • Cada click causa un update (re-render)
  • • El componente NO se desmonta y vuelve a montar
  • • Solo se actualiza el contenido que cambió
  • • El contador de renders aumenta en cada actualización
  • • Revisa la consola para ver los logs de cada update

Demo 3: Timer con limpieza

Demo 3: Limpieza con Cleanup Function

Con limpieza
Sin limpieza (memory leak)

¿Qué está pasando?

  • Cronómetro CORRECTO:
    • • Usa return () => clearInterval()
    • • Cuando lo detienes, limpia el intervalo correctamente
    • • No hay memory leaks
  • Cronómetro INCORRECTO:
    • • NO tiene función de limpieza
    • • El intervalo sigue corriendo en background
    • • Causa memory leaks (fuga de memoria)

Prueba esto:

  1. Abre la consola del navegador (F12)
  2. Inicia el cronómetro INCORRECTO
  3. Déjalo correr 3 segundos
  4. Deténlo con el botón
  5. Observa la consola: veras que sigue contando en background
  6. Ahora prueba el cronómetro CORRECTO y verás que se detiene completamente

A continuación el código de como funcionan estos cronometros:

Imagina un cronometro que se detiene automáticamente cuando el componente desaparece:

plaintext
Cronometro: 5 segundos
 
[Boton: Ocultar cronometro]

Si no limpias el intervalo, seguira corriendo en segundo plano incluso después de ocultar el componente.

código correcto:

jsx
function Cronometro() {
  const [segundos, setSegundos] = useState(0)
 
  useEffect(() => {
    console.log('Cronometro iniciado')
 
    const intervalo = setInterval(() => {
      setSegundos(s => s + 1)
    }, 1000)
 
    // IMPORTANTE: Limpieza
    return () => {
      console.log('Cronometro detenido')
      clearInterval(intervalo)
    }
  }, [])
 
  return <div>Tiempo: {segundos} segundos</div>
}

Sin limpieza (MAL):

jsx
function CronometroMalo() {
  const [segundos, setSegundos] = useState(0)
 
  useEffect(() => {
    setInterval(() => {
      setSegundos(s => s + 1)
    }, 1000)
 
    // Sin return = no limpia = memory leak
  }, [])
 
  return <div>Tiempo: {segundos} segundos</div>
}

El intervalo seguira ejecutandose eternamente, incluso después de que el componente desaparezca.

Casos de uso reales

1. Cargar datos al abrir una página

Este es el patron más frecuente: usar async/await o .then() dentro de useEffect para obtener datos del servidor.

jsx
function PaginaProductos() {
  const [productos, setProductos] = useState([])
  const [cargando, setCargando] = useState(true)
 
  useEffect(() => {
    // Cuando el componente se monta, carga los productos
    fetch('/api/productos')
      .then(res => res.json())
      .then(data => {
        setProductos(data)
        setCargando(false)
      })
  }, []) // Solo al montar
 
  if (cargando) {
    return <div>Cargando productos...</div>
  }
 
  return (
    <div>
      {productos.map(p => (
        <div key={p.id}>{p.nombre}</div>
      ))}
    </div>
  )
}

Ciclo de vida:

  1. Componente se monta
  2. useEffect ejecuta el fetch
  3. Mientras tanto, muestra "Cargando..."
  4. Cuando llegan los datos, actualiza el estado (tip: válida la respuesta con Zod para asegurarte de que la estructura sea correcta)
  5. El componente se re-renderiza con los productos

2. Escuchar eventos del navegador

jsx
function DetectorTeclas() {
  const [tecla, setTecla] = useState(null)
 
  useEffect(() => {
    // Función que se ejecuta cuando presionas una tecla
    const manejarTecla = (evento) => {
      setTecla(evento.key)
    }
 
    // Suscribirse al evento
    window.addEventListener('keydown', manejarTecla)
 
    // Limpieza: desuscribirse cuando el componente se desmonte
    return () => {
      window.removeEventListener('keydown', manejarTecla)
    }
  }, [])
 
  return (
    <div>
      {tecla ? `Presionaste: ${tecla}` : 'Presiona cualquier tecla'}
    </div>
  )
}

Por qué es importante la limpieza: Si tienes 10 instancias de este componente que se montan y desmontan, sin limpieza tendrias 10 listeners activos consumiendo memoria.

3. Actualizar el título de la página

jsx
function PaginaProducto({ nombreProducto }) {
  useEffect(() => {
    // Actualizar el título del navegador
    document.title = `${nombreProducto} - Mi Tienda`
 
    // Limpieza: restaurar el título original
    return () => {
      document.title = 'Mi Tienda'
    }
  }, [nombreProducto]) // Se ejecuta cuando nombreProducto cambia
 
  return <div>Viendo: {nombreProducto}</div>
}

Ciclo de vida:

  1. Componente se monta con "Camisa Azul"
  2. useEffect cambia el título a "Camisa Azul - Mi Tienda"
  3. Usuario navega a otro producto "Pantalon Negro"
  4. Props cambian, useEffect se ejecuta de nuevo
  5. título cambia a "Pantalon Negro - Mi Tienda"
  6. Si el componente se desmonta, título vuelve a "Mi Tienda"

4. Guardar en localStorage

jsx
function FormularioConGuardado() {
  const [nombre, setNombre] = useState('')
 
  // Cargar desde localStorage al montar
  useEffect(() => {
    const guardado = localStorage.getItem('nombreFormulario')
    if (guardado) {
      setNombre(guardado)
    }
  }, [])
 
  // Guardar en localStorage cada vez que nombre cambie
  useEffect(() => {
    localStorage.setItem('nombreFormulario', nombre)
  }, [nombre])
 
  return (
    <input
      value={nombre}
      onChange={(e) => setNombre(e.target.value)}
      placeholder="Tu nombre"
    />
  )
}

Ciclo de vida:

  1. Componente se monta
  2. Primer useEffect carga el valor guardado
  3. Usuario escribe "A" -> nombre cambia -> segundo useEffect guarda
  4. Usuario escribe "n" -> nombre cambia -> segundo useEffect guarda
  5. Usuario recarga la página -> primer useEffect carga "An"

Errores comunes y como evitarlos

Error 1: Olvidar el array de dependencias

jsx
// MAL: Se ejecuta en cada render
useEffect(() => {
  console.log('Esto se ejecuta MUCHO')
  fetch('/api/datos')
    .then(...)
})
 
// BIEN: Solo al montar
useEffect(() => {
  console.log('Esto se ejecuta una vez')
  fetch('/api/datos')
    .then(...)
}, []) // Array vacio

Sin el array de dependencias, el efecto se ejecuta después de cada render, causando requests infinitos.

Error 2: Dependencias incorrectas

jsx
function Buscador() {
  const [query, setQuery] = useState('')
  const [resultados, setResultados] = useState([])
 
  // MAL: query esta en el efecto pero no en dependencias
  useEffect(() => {
    fetch(`/api/buscar?q=${query}`)
      .then(res => res.json())
      .then(setResultados)
  }, []) // debería incluir [query]
 
  return <input onChange={(e) => setQuery(e.target.value)} />
}

El efecto solo se ejecuta al montar, nunca cuando query cambia. La búsqueda no funcionara.

Corrección:

jsx
useEffect(() => {
  fetch(`/api/buscar?q=${query}`)
    .then(res => res.json())
    .then(setResultados)
}, [query]) // Ahora si funciona

Error 3: No limpiar suscripciones

jsx
// MAL: Memory leak
function Chat() {
  useEffect(() => {
    const socket = new WebSocket('ws://servidor.com')
 
    socket.onmessage = (msg) => {
      console.log(msg)
    }
 
    // Sin limpieza: la conexión queda abierta
  }, [])
 
  return <div>Chat</div>
}
 
// BIEN: Con limpieza
function Chat() {
  useEffect(() => {
    const socket = new WebSocket('ws://servidor.com')
 
    socket.onmessage = (msg) => {
      console.log(msg)
    }
 
    return () => {
      socket.close() // Cerrar conexión al desmontar
    }
  }, [])
 
  return <div>Chat</div>
}

Error 4: múltiples efectos que deberian ser uno

jsx
// Confuso: Tres efectos relacionados
function PerfilUsuario({ userId }) {
  const [usuario, setUsuario] = useState(null)
  const [posts, setPosts] = useState([])
  const [amigos, setAmigos] = useState([])
 
  useEffect(() => {
    fetch(`/api/usuario/${userId}`).then(...)
  }, [userId])
 
  useEffect(() => {
    fetch(`/api/posts/${userId}`).then(...)
  }, [userId])
 
  useEffect(() => {
    fetch(`/api/amigos/${userId}`).then(...)
  }, [userId])
 
  return <div>...</div>
}
 
// MEJOR: Un solo efecto
function PerfilUsuario({ userId }) {
  const [usuario, setUsuario] = useState(null)
  const [posts, setPosts] = useState([])
  const [amigos, setAmigos] = useState([])
 
  useEffect(() => {
    // Cargar todo relacionado con el usuario
    Promise.all([
      fetch(`/api/usuario/${userId}`),
      fetch(`/api/posts/${userId}`),
      fetch(`/api/amigos/${userId}`)
    ]).then(([usuarioData, postsData, amigosData]) => {
      setUsuario(usuarioData)
      setPosts(postsData)
      setAmigos(amigosData)
    })
  }, [userId])
 
  return <div>...</div>
}

Error 5: Actualizar state en el momento equivocado

jsx
// MAL: setState directo en el cuerpo del componente
function Contador() {
  const [count, setCount] = useState(0)
 
  setCount(count + 1) // Esto causa un loop infinito
 
  return <div>{count}</div>
}
 
// BIEN: setState en un evento o useEffect
function Contador() {
  const [count, setCount] = useState(0)
 
  const incrementar = () => {
    setCount(count + 1)
  }
 
  return (
    <div>
      {count}
      <button onClick={incrementar}>+1</button>
    </div>
  )
}

Diagrama del flujo completo

aquí hay una visualización del ciclo de vida completo:

plaintext
Usuario abre la app
        |
+-------------------------------+
|   MOUNTING                    |
|   - Constructor se ejecuta    |
|   - useEffect sin deps []     |
|   - Componente aparece        |
+-------------------------------+
        |
+-------------------------------+
|   MONTADO (viviendo)          |
|   - Esperando interacciones   |
+-------------------------------+
        |
    Algo cambia?
    (state, props, padre)
        | SI
+-------------------------------+
|   UPDATING                    |
|   - Re-render                 |
|   - useEffect con deps        |
|   - Pantalla se actualiza     |
+-------------------------------+
        |
    Vuelve a estar montado
        |
    Usuario se va?
    Condición false?
        | SI
+-------------------------------+
|   UNMOUNTING                  |
|   - Cleanup functions         |
|   - return de useEffect       |
|   - Componente desaparece     |
+-------------------------------+
        |
    Componente muerto

Resumen visual

EtapaCuando ocurreQue hacer aquíEjemplo
MountingComponente aparece por primera vezCargar datos, configurar cosasuseEffect(() => { fetch() }, [])
UpdatingState o props cambianReaccionar a cambiosuseEffect(() => { }, [variable])
UnmountingComponente desapareceLimpiar: timers, eventos, conexionesreturn () => { clearInterval() }

Consejos finales

1. Piensa en términos de efectos, no de ciclo de vida

En lugar de pensar "necesito hacer esto en componentDidMount", piensa "necesito hacer esto cuando el componente se monta".

2. Un efecto por responsabilidad

No mezcles lógica no relacionada en un solo useEffect. Si cargas datos y también pones un timer, usa dos efectos separados.

3. Siempre limpia

Si creas algo que consume recursos (timers, conexiones, listeners), SIEMPRE limpia en el return.

4. Usa las dependencias correctamente

Si usas una variable dentro del efecto, incluyela en el array de dependencias. ESLint te ayudara con esto.

5. No optimices prematuramente

Empieza simple. React es eficiente por defecto. Optimiza solo si tienes problemas de rendimiento medibles.

Proximos pasos

Ahora que entiendes el ciclo de vida:

  1. práctica con los ejemplos de este artículo
  2. Abre la consola y observa cuando se ejecutan los efectos
  3. Crea un componente que cargue datos y limpielos correctamente
  4. Lee sobre useEffect avanzado: dependencies, cleanup, custom hooks

Recursos adicionales

Resumen

Con estos conceptos claros, ya sabes como y cuando ejecutar código en tus componentes. El ciclo de vida es la base para cargar datos correctamente, limpiar recursos y evitar memory leaks en tus aplicaciones React.

#react#lifecycle#useEffect#hooks

Preguntas frecuentes

¿Cuál es la diferencia entre los métodos de ciclo de vida de clase y los hooks?

Los métodos de ciclo de vida como componentDidMount y componentWillUnmount solo funcionan en componentes de clase. Los hooks como useEffect reemplazan estos métodos en componentes funcionales, ofreciendo una forma más simple y composable de manejar efectos secundarios.

¿Cómo funciona la limpieza (cleanup) en useEffect?

La función que retornas dentro de useEffect se ejecuta cuando el componente se desmonta o antes de que el efecto se vuelva a ejecutar. Es fundamental para limpiar timers con clearInterval, cerrar conexiones WebSocket, o remover event listeners y así evitar fugas de memoria.

¿Cuándo usar useEffect con array vacio vs con dependencias?

Usa useEffect con array vacio [] cuando quieras ejecutar código solo una vez al montar el componente, como cargar datos iniciales. Usa dependencias [variable] cuando necesites reaccionar a cambios especificos, como actualizar resultados de búsqueda cuando cambia el query.