Ciclo de Vida de la App (React Native) - chrisfalla/Frontend_La_Brujula_Llanera GitHub Wiki

Ciclo de Vida de una App en React Native (Guía Completa)

Esta guía explica cómo manejar y monitorear el ciclo de vida de una app desarrollada con React Native, incluyendo el comportamiento de los componentes, las pantallas, el estado del sistema operativo, y casos de uso como minimizar la app, cambiar a otra app, volver, y más.



🧠 1. Ciclo de Vida de los Componentes

React Native hereda el ciclo de vida de React. Esto aplica tanto para componentes funcionales como de clase.

✅ Ciclo de Vida en Componentes Funcionales (Hooks)

import React, { useEffect } from 'react';

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

  return () => {
    console.log('Componente desmontado');
  };
}, []);

✅ Ciclo de Vida en Clases

class MyComponent extends React.Component {
  componentDidMount() {
    console.log('Componente montado');
  }

  componentWillUnmount() {
    console.log('Componente desmontado');
  }

  render() {
    return <Text>Hola</Text>;
  }
}

👥 2. Ciclo de Vida de Pantallas con React Navigation

En React Native no hay un ciclo de vida nativo de pantallas como en Android/iOS. Se usa React Navigation para gestionar su enfoque o visibilidad.

useFocusEffect

import { useFocusEffect } from '@react-navigation/native';

useFocusEffect(
  React.useCallback(() => {
    console.log('Pantalla visible');

    return () => {
      console.log('Pantalla dejó de estar visible');
    };
  }, [])
);

useIsFocused

import { useIsFocused } from '@react-navigation/native';
const isFocused = useIsFocused();

useEffect(() => {
  if (isFocused) {
    console.log('Pantalla está activa');
  }
}, [isFocused]);

📱 3. Estados de la App a Nivel de Sistema Operativo

Puedes controlar si la app está en primer plano, en segundo plano o inactiva con AppState:

import { AppState } from 'react-native';

useEffect(() => {
  const subscription = AppState.addEventListener('change', nextState => {
    console.log('Estado de la app:', nextState);
  });

  return () => subscription.remove();
}, []);

Estados posibles:

  • active: App visible y usable.
  • background: Usuario salió de la app.
  • inactive: Transición o interrupción (iOS).

⛔️ 4. Detectar Cierre Completo de la App

React Native no puede detectar directamente si una app fue cerrada completamente ("killed"). Pero puedes inferirlo usando almacenamiento persistente:

Estrategia:

  1. Guarda lastSeen con AsyncStorage al ir a background.
  2. Al iniciar la app, verifica si ha pasado mucho tiempo o si no existe lastSeen.
import AsyncStorage from '@react-native-async-storage/async-storage';

const saveAppExitTime = async () => {
  await AsyncStorage.setItem('lastSeen', new Date().toISOString());
};

const checkIfAppWasKilled = async () => {
  const lastSeen = await AsyncStorage.getItem('lastSeen');
  if (!lastSeen) return true;
};

🚪 5. Casos de Uso y Configuración

📅 Caso 1: El usuario se cambia a otra app y vuelve

  • Detectado por AppState al pasar de activebackground y luego backgroundactive.
  • Ubicación del código: dentro de App.tsx o un AppContext global.

🚶‍♂️ Caso 2: El usuario presiona el botón de inicio del sistema y vuelve

  • Mismo comportamiento que el anterior.
  • Puedes usar esto para pausar audio/video, cerrar modales, guardar datos.

Caso 3: El usuario mata la app desde el sistema

  • No hay notificación directa.
  • Solución: persistir un estado al background y compararlo al iniciar la app.

🚪 Caso 4: El usuario enciende el teléfono e inicia la app

  • Se ejecuta desde index.js > App.tsx > hooks de tu pantalla inicial.
  • Puedes cargar datos desde almacenamiento persistente para "restaurar" el estado anterior.

📂 6. Ubicación del Código

Tipo de control Ubicación recomendada
AppState global App.tsx
Estado por pantalla Dentro del componente de la pantalla
Restauración de estado En un Provider o en el App.tsx
Persistencia Usar AsyncStorage, Zustand o Redux-Persist

🔄 7. Ejemplo Completo

import React, { useEffect } from 'react';
import { View, Text, AppState } from 'react-native';
import { useFocusEffect } from '@react-navigation/native';

export default function HomeScreen() {
  useFocusEffect(
    React.useCallback(() => {
      console.log('Pantalla visible');
      return () => console.log('Pantalla NO visible');
    }, [])
  );

  useEffect(() => {
    const subscription = AppState.addEventListener('change', nextState => {
      console.log('Estado de la app:', nextState);
    });

    return () => subscription.remove();
  }, []);

  return (
    <View>
      <Text>Inicio</Text>
    </View>
  );
}

💡 Buenas Prácticas

  • ✅ Usa useFocusEffect para detectar visibilidad de pantallas.
  • ✅ Usa AppState solo cuando sea crítico (ej. reproducir/pausar medios).
  • ✅ Guarda datos críticos antes de pasar a background.
  • 🤝 Implementa redux-persist, zustand/persist o AsyncStorage para restaurar contexto.

🌍 Recursos


Esta guía está pensada para incluirla en una wiki de proyecto o como material de soporte para onboarding de nuevos desarrolladores en React Native.

⚠️ **GitHub.com Fallback** ⚠️