React Native: Provider de animación con confetti

Clase 17 de 23Curso de Fundamentos de React Native

Resumen

Acelera tu app de hábitos con una integración clara: conecta el provider al área de explorer, añade animaciones con confetti y consume mensajes de motivación mediante un servicio simulado. Aquí verás cómo aprovechar el context, tipar correctamente y disparar una animación con mensaje aleatorio al completar un hábito del día de hoy.

¿Cómo conectar el provider al explorer y los hábitos sugeridos?

El primer paso es mover la lógica de creación de hábitos al context. En lugar de usar la función de explorer, se importa desde el hook useHabit el addHabit y se llama con el título y la prioridad. La interfaz no cambia, solo se agrega una línea para usar el context.

  • Importar addHabit desde useHabit.
  • Pasar title y priority al crear el hábito.
  • Mantener el mismo flujo de selección en explorer.
  • Ver la actualización inmediata en home con los hábitos sugeridos.

Ejemplo orientativo:

// Dentro de explorer
const { addHabit } = useHabit();
addHabit({ title, priority });

¿Qué cambia con add habit en el context?

  • Una sola fuente de verdad: el context controla creación y estado.
  • Sincronización automática: lo seleccionado en explorer aparece en home.
  • Menos acoplamiento: se evita depender de funciones locales de explorer.

¿Cómo se reflejan los hábitos sugeridos en home?

  • Al seleccionar en explorer, se agrega a los hábitos personales.
  • La UI responde de inmediato gracias al context.

¿Cómo agregar animación con React Native Confetti y un provider celebrate?

Se instala la librería de React Native Confetti y se crea un nuevo provider dedicado al confetti, que actúa como centro de control de la animación.

  • Estados con useState para visible y message.
  • Control de inicio y fin para no sobreescribir animaciones.
  • Dos vistas de confetti (izquierda y derecha) para cubrir la pantalla.
  • Estilos mínimos para posicionamiento.

Ejemplo orientativo del provider:

export const CelebrateProvider = ({ children }) => {
  const [visible, setVisible] = useState(false);
  const [message, setMessage] = useState("");

  const start = (msg: string) => { setMessage(msg); setVisible(true); };
  const end = () => setVisible(false);

  return (
    <CelebrateContext.Provider value={{ start, end, visible, message }}>
      {children}
      {/* Confetti izquierda y derecha */}
    </CelebrateContext.Provider>
  );
};

¿Dónde se monta el provider en la app?

  • Importar el provider y envolver el árbol principal.
  • Ubicarlo como etiqueta padre del stack o de las tabs.
// App root
<CelebrateProvider>
  <Tabs />
</CelebrateProvider>

¿Cómo crear un servicio con fetch, endpoint y mensajes de motivación?

Se simula un servicio externo: una carpeta services/ con un archivo motivation.ts que devuelve mensajes aleatorios. Puede leer un endpoint de process.env o usar un mock local.

  • Variable endpoint para URL externa.
  • Petición con fetch en método post.
  • body con nombre y título del hábito.
  • Validación de response.ok; si falla: throw new Error("endpoint... falló").
  • data = await res.json() y data.message.toString().
  • Si no hay respuesta, fallback al mock local.
  • Registro de error con warn en consola.

Ejemplo orientativo del servicio:

export async function getMotivation({ name, habitTitle }) {
  try {
    if (endpoint) {
      const res = await fetch(endpoint, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name, habitTitle })
      });
      if (!res.ok) throw new Error("endpoint... falló");
      const data = await res.json();
      return (data?.message ?? "").toString();
    }
    // Fallback: mock local
    return localMessages[0];
  } catch (e) {
    console.warn(e);
    return localMessages[0];
  }
}

¿Cómo integrar confetti y mensajes en toggle habit?

Al presionar un hábito se decide si se completó “hoy” y se lanza el confetti con un mensaje del servicio. Además, se delega el cambio de estado a toggleHabit del context.

  • Leer lastDoneAt del item.
  • Verificar si es el mismo día.
  • Si se completa hoy: actualizar fecha, llamar toggleHabit, pedir mensaje al servicio y start del provider de Celebrate.
  • Si se desmarca: restaurar estado y llamar toggleHabit.

Ejemplo orientativo en el listado tipado:

type Habit = { id: string; title: string; lastDoneAt?: Date };

const renderItem: ListRenderItem<Habit> = ({ item }) => (
  <HabitCard onPress={async () => {
    const didToday = isSameDay(item.lastDoneAt, new Date());
    if (!didToday) {
      await toggleHabit(item.id);
      const msg = await getMotivation({ name, habitTitle: item.title });
      celebrate.start(msg);
    } else {
      await toggleHabit(item.id);
    }
  }} />
);
  • En el render, tipar ListRenderItem<Habit> en lugar de any.
  • Pasar si “se hizo hoy” en vez de “completo”.
  • Si no ves cambios, presiona R en la terminal para recargar.

¿Te gustaría compartir cómo mostrarías tus propios mensajes motivacionales o cómo estructurarías el provider de confetti? Deja tus ideas y dudas en los comentarios.