10.3-43. Hook de efecto - useEffect

 

Dominando el Hook useEffect en React Native

El hook useEffect es esencial para manejar efectos secundarios en tus componentes, como llamadas a APIs, suscripciones o manipulación del DOM. Vamos a explorar cómo usarlo efectivamente.

🧠 Conceptos Clave de useEffect

  • Efectos secundarios: Operaciones que ocurren después del renderizado

  • Fases de ejecución: Se ejecuta después del montaje y actualizaciones

  • Dependencias: Controla cuándo se vuelve a ejecutar el efecto

🛠 Sintaxis Básica

javascript
import React, { useState, useEffect } from 'react';
import { View, Text, Button } from 'react-native';

const ExampleComponent = () => {
  const [count, setCount] = useState(0);

  // Efecto básico
  useEffect(() => {
    console.log(`El contador es: ${count}`);
    
    // Función de limpieza (opcional)
    return () => {
      console.log('Limpieza del efecto');
    };
  }, [count]); // Dependencias

  return (
    <View>
      <Text>Contador: {count}</Text>
      <Button title="Incrementar" onPress={() => setCount(c => c + 1)} />
    </View>
  );
};

🔄 Tipos de Efectos

1. Ejecución única (al montar)

javascript
useEffect(() => {
  console.log('Solo al montar el componente');
  fetchData(); // Llamada API inicial
}, []); // Array vacío = sin dependencias

2. Ejecución condicional (cuando cambian dependencias)

javascript
useEffect(() => {
  console.log('Cuando count cambia:', count);
}, [count]); // Se ejecuta cuando count cambia

3. Efecto con limpieza

javascript
useEffect(() => {
  const subscription = someObservable.subscribe();
  
  return () => {
    subscription.unsubscribe(); // Limpieza al desmontar
  };
}, []);

💡 Caso Práctico: Llamada a API

javascript
const UserList = () => {
  const [users, setUsers] = useState([]);
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    const fetchUsers = async () => {
      setIsLoading(true);
      try {
        const response = await fetch('https://api.example.com/users');
        const data = await response.json();
        setUsers(data);
      } catch (error) {
        console.error('Error fetching users:', error);
      } finally {
        setIsLoading(false);
      }
    };

    fetchUsers();
  }, []); // Solo al montar

  if (isLoading) return <ActivityIndicator />;

  return (
    <FlatList
      data={users}
      renderItem={({ item }) => <UserItem user={item} />}
    />
  );
};

🚨 Errores Comunes y Buenas Prácticas

❌ Olvidar dependencias

javascript
// MAL - Falta count como dependencia
useEffect(() => {
  console.log(count);
}, []);

// BIEN
useEffect(() => {
  console.log(count);
}, [count]);

✅ Usar múltiples efectos para separar preocupaciones

javascript
// Separar lógica de usuario y tema
useEffect(() => { /* Lógica usuario */ }, [userId]);
useEffect(() => { /* Lógica tema */ }, [theme]);

⚠️ Efectos infinitos

javascript
// CUIDADO - Ciclo infinito
useEffect(() => {
  setCount(count + 1); // Actualiza state que es dependencia
}, [count]);

🎯 Ejemplo Avanzado: Geolocalización

javascript
const LocationTracker = () => {
  const [location, setLocation] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    let watchId;
    
    const handleSuccess = (position) => {
      setLocation({
        latitude: position.coords.latitude,
        longitude: position.coords.longitude
      });
    };

    const handleError = (error) => {
      setError(error.message);
    };

    // Iniciar seguimiento
    watchId = Geolocation.watchPosition(
      handleSuccess,
      handleError,
      { enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
    );

    // Limpieza
    return () => {
      if (watchId) {
        Geolocation.clearWatch(watchId);
      }
    };
  }, []);

  return (
    <View>
      {error ? (
        <Text>Error: {error}</Text>
      ) : location ? (
        <Text>Lat: {location.latitude}, Long: {location.longitude}</Text>
      ) : (
        <Text>Obteniendo ubicación...</Text>
      )}
    </View>
  );
};

📌 Conclusión

  • useEffect maneja efectos secundarios en componentes funcionales

  • Dependencias controlan la frecuencia de ejecución

  • Limpieza es esencial para evitar memory leaks

  • Separar efectos por preocupaciones mejora el mantenimiento

¿Qué otros casos de uso interesantes has implementado con useEffect? ¡Compártelos en los comentarios!

Comentarios

Entradas más populares de este blog

4.2-12. Componentes esenciales

7.5-10. ¿Como funcionan los estilos en React Native?

7.1-19. Creación de estilos