Domina la gestión de estado local complejo en React con useReducer y TypeScript mientras construyes un emoji todo list. Verás cuándo useState se queda corto, cómo se coordinan estado, acciones y reducer, y cómo tipar datos clave para agregar y eliminar elementos de forma clara y mantenible.
UseReducer en una lista de emojis tipo todo
Antes de escribir código, se plantea un flujo simple y potente: un input donde escribes "eat", "sleep" o "exercise", presionas Enter y se renderiza el emoji correspondiente; al hacer clic sobre un ítem, se elimina. Este comportamiento requiere leer y modificar estado de manera segura, algo que useReducer resuelve con una arquitectura explícita.
¿Por qué useState se queda corto para listas complejas?
- Agregar, eliminar y actualizar implica múltiples funciones y estados derivados.
- La lógica se dispersa y crece el riesgo de errores.
- useReducer centraliza la lógica: una sola puerta para mutar el estado.
¿Qué interacción tendrá el usuario en la UI?
- Escribe un texto como "eat" y presiona Enter.
- El texto se convierte en emoji y se agrega a la lista.
- Haz clic sobre un emoji para eliminarlo.
- El flujo es inmediato y claro para tareas completadas.
Actores del estado y su flujo de comunicación
Para un manejo robusto se definen tres actores: estado, acciones y reducer. Esta separación facilita razonar sobre qué se guarda, qué se quiere hacer y cómo se transforma el estado.
¿Qué representa cada actor en useReducer?
- Estado: bolsa o maleta con toda la información. Inicia como estado inicial vacío.
- Acciones: instrucciones como "add" y "remove" que describen la intención.
- Reducer: la función que decide cómo agregar o eliminar en el estado.
¿Cómo se comunican componente, acción y reducer?
- El componente solo lee del estado para renderizar la UI.
- El componente no modifica el estado directamente.
- El componente expresa una intención: agregar o eliminar.
- Esa intención se envía como acción con un payload.
- El reducer es el único que modifica el estado.
- Tras el cambio, el componente vuelve a leer y renderiza.
¿Qué casos de uso cubren las acciones add y remove?
- Agregar: crea un nuevo todo a partir del texto ingresado.
- Eliminar: remueve un todo por su ID, típico con filter sobre el array.
- Ambas acciones mantienen la lógica concentrada en el reducer.
Tipos en TypeScript y configuración del proyecto
Definir tipos primero ordena el pensamiento: se clarifica la forma de los datos, entradas y salidas. Aquí se tipan el todo, el state, las action y el estado inicial.
¿Cómo declarar los tipos state, todo y action?
// Forma de un todo
type todo = {
id: number;
text: string;
};
// Estado general
type state = {
todos: todo[];
};
// Acciones permitidas
type action =
| { type: 'add_todo'; payload: string }
| { type: 'remove'; payload: number };
- todo: usa un id numérico para identificar y eliminar.
- state: almacena un arreglo de todos.
- action: describe la intención y el payload que necesita cada caso.
¿Cómo se define el estado inicial tipado?
const initialState: state = {
todos: [],
};
- Arranca vacío para ir "llenando la maleta" con nuevos todos.
- El tipado evita inconsistencias al manipular el estado.
¿Cómo crear el proyecto con Vite y React TypeScript?
- Crea el proyecto con Vite y selecciona React + TypeScript.
- Instala dependencias y corre el servidor.
- Crea el componente en src/components/todoList.tsx.
npm create vite@latest
# Nombre: MyUseReducerApp
# Plantilla: React + TypeScript
cd MyUseReducerApp
npm install
npm run dev
- Estructura inicial lista para añadir el reducer y despachar acciones.
- Próximo paso: implementar el reducer y el dispatch desde el componente.
¿Te gustaría ver el reducer en acción y el mapeo de texto a emoji paso a paso? Deja tus dudas o ideas en los comentarios.