Volver a la página principal
domingo 29 septiembre 2024
15

¿Qué es useEffect en React?

En términos simples, useEffect permite ejecutar código después de que el componente se haya renderizado, y también ofrece una manera de limpiar esos efectos cuando el componente se desmonta o cuando cambian las dependencias especificadas.

Sintaxis Básica

import React, { useEffect } from 'react';

function MiComponente() {
  useEffect(() => {
    console.log('Componente montado');

    // Cleanup opcional que se ejecuta cuando el componente se desmonta
    return () => {
      console.log('Componente desmontado');
    };
  }, []); // Array de dependencias vacío: el efecto solo se ejecuta en el montaje y desmontaje

  return <div>Hola, soy un componente con useEffect</div>;
}

La estructura básica del useEffect es la siguiente:

1. Función de efecto: La primera parte de useEffect es una función que contiene el código que se ejecutará después de que React haya renderizado el componente.

2. Array de dependencias: La segunda parte (opcional) es un array que define cuándo debe volver a ejecutarse el efecto. Este array de dependencias le dice a React qué valores debe observar para determinar si debe ejecutar nuevamente el efecto.

Conceptos Clave de useEffect

1. Montaje y Desmontaje: Cuando se pasa un array de dependencias vacío ([]), el efecto se ejecuta solo una vez, similar a componentDidMount en los componentes de clase. Si el efecto tiene un retorno, esa función se ejecuta cuando el componente se desmonta, equivalente a componentWillUnmount.

2. Dependencias: Cuando se proporciona un array con variables, el efecto se ejecuta cada vez que alguna de esas variables cambie. Esto permite controlar cuándo React debe volver a ejecutar el efecto.

3. Actualización: Si se omite el array de dependencias, el efecto se ejecuta después de cada renderizado del componente, es decir, después de cada cambio de estado o de props. Esto no es ideal en la mayoría de los casos, ya que puede provocar comportamientos no deseados y afectar el rendimiento.

Ejemplos Comunes de Uso

A continuación, se presentan algunos casos de uso comunes de useEffect en los componentes de React.

1. Llamadas a APIs

Una de las aplicaciones más comunes de useEffect es hacer solicitudes a APIs. En este caso, se usa para cargar datos cuando el componente se monta.

import React, { useState, useEffect } from 'react';

function DatosUsuario({ userId }) {
  const [userData, setUserData] = useState(null);

  useEffect(() => {
    // Función asíncrona para obtener datos
    const fetchData = async () => {
      const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
      const data = await response.json();
      setUserData(data);
    };
    
    fetchData();
  }, [userId]); // El efecto se ejecuta cada vez que cambia el `userId`

  return (
    <div>
      {userData ? (
        <div>
          <h2>{userData.name}</h2>
          <p>Email: {userData.email}</p>
        </div>
      ) : (
        'Cargando...'
      )}
    </div>
  );
}

En este ejemplo:

  • Se declara un estado userData para almacenar los datos del usuario.
  • useEffect se usa para hacer una llamada a la API cuando el componente se monta o cuando cambia el valor de userId.
  • El array de dependencias [userId] asegura que el efecto se ejecute solo cuando userId cambie.

2. Suscripción a Eventos

Puedes usar useEffect para suscribirte a eventos y luego limpiar la suscripción cuando el componente se desmonta.

import React, { useEffect, useState } from 'react';

function VentanaSize() {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);

    window.addEventListener('resize', handleResize);

    // Cleanup para remover el listener cuando el componente se desmonte
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []); // El efecto solo se ejecuta una vez cuando el componente se monta

  return <p>Ancho de la ventana: {width}px</p>;
}

En este ejemplo:

  • Se utiliza useEffect para añadir un listener de eventos resize de la ventana.
  • El efecto se ejecuta una vez al montar el componente, y cuando el componente se desmonta, la función de limpieza (window.removeEventListener) elimina el listener para evitar fugas de memoria.

Evitar Comportamientos Inesperados

  • Efectos sin dependencias: Si no se incluye un array de dependencias, el efecto se ejecuta en cada renderizado, lo que puede provocar problemas de rendimiento y bucles infinitos en ciertos casos.
  • Uso de funciones asíncronas: Aunque useEffect no puede ser directamente una función asíncrona (async), se pueden definir funciones asíncronas dentro de él y llamarlas. Otra opción es usar then y catch para manejar promesas.

Reglas de los Hooks

Al igual que otros hooks en React, useEffect sigue algunas reglas:

1. Llamar a hooks en la parte superior del componente: useEffect y otros hooks deben ser llamados en la parte superior de un componente funcional, y nunca dentro de condicionales o bucles. Esto asegura que React mantenga el estado de los hooks correctamente.

2. No llamar a hooks dentro de funciones ordinarias: Los hooks deben ser utilizados exclusivamente en componentes funcionales o en custom hooks.

Comparación con el Ciclo de Vida de los Componentes de Clase

Antes de la introducción de hooks, los componentes de clase de React usaban métodos de ciclo de vida como componentDidMount, componentDidUpdate y componentWillUnmount para manejar efectos secundarios. La introducción de useEffect simplificó este proceso al combinar estas funcionalidades en un solo hook:

  • componentDidMount y componentDidUpdateuseEffect
  • componentWillUnmount → Función de limpieza dentro de useEffect

Uso Avanzado de useEffect

1. Evitar Dependencias Innecesarias: Asegúrate de definir correctamente el array de dependencias para evitar que el efecto se ejecute innecesariamente. React puede mostrar advertencias si las dependencias están mal definidas.

2. Memorización de funciones: Si pasas funciones al efecto, usa useCallback para evitar crear nuevas instancias de la función en cada renderizado.

useEffect(() => {
  const id = setInterval(() => {
    setTime(new Date());
  }, 1000);

  return () => clearInterval(id);
}, []); // El array vacío asegura que el intervalo se configure solo una vez

En este ejemplo, setInterval se configura una sola vez en el montaje, y clearInterval limpia el intervalo en el desmontaje.

Conclusión

useEffect es una herramienta poderosa para manejar efectos secundarios en los componentes funcionales de React. Comprender cómo y cuándo utilizar useEffect es crucial para crear aplicaciones React eficientes y mantenibles. Al controlar correctamente el ciclo de vida de los efectos y definir las dependencias adecuadas, puedes crear aplicaciones reactivas y optimizadas sin las complejidades de los componentes de clase.

Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer