Crear una Emoji To‑Do List con Redux Toolkit y React Redux es más simple de lo que parece. Aquí verás cómo tipar dispatch, leer el estado global con selector, mapear texto a emojis y despachar acciones para agregar y eliminar tareas, todo con TypeScript y un functional component.
¿Cómo se configura Redux Toolkit y React Redux en el proyecto?
Para usar el estado global necesitas instalar y configurar React Redux. Luego, importa el Provider y envuelve el componente principal con el store para que cualquier componente pueda acceder al estado.
¿Qué instalar y cómo importar React Redux?
- Instala la librería: npm install react-redux.
- Importa useDispatch y useSelector desde react-redux.
- Usa Provider para inyectar el store.
// main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import { store } from './app/store';
import TodoList from './components/TodoList';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<Provider store={store}>
<TodoList />
</Provider>
</React.StrictMode>
);
¿Cómo tipar AppDispatch y RootState en TypeScript?
- Importa los tipos creados en el store: AppDispatch y RootState.
- Tipa dispatch con AppDispatch para despachar acciones con seguridad.
- Tipa useSelector con RootState para acceder al estado con autocompletado.
import type { AppDispatch, RootState } from '../app/store';
¿Cómo se construye el componente TodoList con TypeScript?
El componente parte de un functional component con estado local para el texto del input, funciones para agregar y eliminar, y un mapeo de texto a emojis. La tecla Enter dispara la acción de agregar.
¿Cómo gestionar el estado local con useState?
- Crea un estado local para el texto: todoText.
- Limpia el estado tras agregar para escribir un nuevo todo.
¿Cómo mapear texto a emojis con toLowerCase?
- Usa un objeto como emojiMap para asociar palabras a emojis.
- Normaliza con toLowerCase y define un fallback: si no hay mapeo, usa el texto original.
¿Cómo capturar Enter y despachar addTodo?
- Escucha onKeyDown en el input.
- Si la tecla es Enter, ejecuta handleAddTodo.
// TodoList.tsx
import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import type { AppDispatch, RootState } from '../app/store';
import { addTodo, removeTodo } from '../features/todos/todoActions';
type EmojiMap = { [key: string]: string };
const emojiMap: EmojiMap = {
eat: '🍔',
sleep: '🛏️',
exercise: '🏋️',
};
const TodoList: React.FC = () => {
const dispatch = useDispatch<AppDispatch>();
const [todoText, setTodoText] = useState('');
const handleAddTodo = () => {
const mappedText = emojiMap[todoText.toLowerCase()] || todoText;
const trimmed = mappedText.trim();
if (!trimmed) return;
dispatch(addTodo(trimmed));
setTodoText('');
};
const handleRemoveTodo = (id: number) => {
dispatch(removeTodo(id));
};
const todos = useSelector((state: RootState) => state.todos);
return (
<div>
<p>Made with Redux Toolkit</p>
<h1>Emoji To Do List</h1>
<input
type="text"
value={todoText}
onChange={(e) => setTodoText(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') handleAddTodo();
}}
placeholder="add a new todo"
/>
<ul>
{todos.map((todo) => (
<li key={todo.id} onClick={() => handleRemoveTodo(todo.id)}>
{todo.text}
</li>
))}
</ul>
</div>
);
};
export default TodoList;
¿Qué habilidades y conceptos clave se practican?
Este flujo integra desde la configuración del store hasta el renderizado de la lista con interacciones del usuario. Refuerza patrones modernos con Redux Toolkit y tipado estricto con TypeScript.
¿Qué keywords y patrones practicar?
- Reducers, acciones y dispatch: estructura para actualizar el estado global.
- useDispatch y useSelector: lectura y escritura en el store desde UI.
- AppDispatch y RootState: tipado de dispatch y del selector.
- Estado local con useState: manejo del texto del input antes de despachar.
- Mapeo de emojis: objeto clave-valor con tipo {[key: string]: string}.
- Normalización: uso de toLowerCase y fallback al texto original.
- Eventos de teclado y clic: onKeyDown con tecla Enter y onClick para eliminar por ID.
- Renderizado de listas: uso de map, key única y li interactiva.
- Provider y store: acceso al estado global desde el árbol de componentes.
¿Qué diferencias se mencionan con useReducer y Substand?
- useReducer: recomendado para estado local complejo en un solo componente.
- Redux: pensado para estado global compartido entre múltiples componentes.
- Substand: se adelanta como alternativa para simplificar acciones y reducers con un enfoque distinto de estado global.
¿Quieres que revisemos tu implementación, nombres de tipos o estructura de carpetas para pulirla? Cuéntame en qué parte te gustaría profundizar.