Contenido del curso

Herramientas avanzadas: escalabilidad, organización y persistencia

Cómo crear addTodo con Context API

Resumen

Aprender a crear la función addTodo con Context API en React te permite conectar un formulario con el estado global de tu aplicación para guardar tareas en local storage. Esta guía es para quienes ya manejan hooks y quieren entender cómo separar estado local y global en una to-do app.

¿Cómo conectar un formulario con el contexto global en React?

Dentro del componente TodoForm consumimos el contexto con React.useContext(TodoContext) y extraemos dos propiedades clave: setOpenModal para cerrar el modal y addTodo para guardar la nueva tarea. Así, cualquier botón del formulario puede comunicarse con el estado global sin importar la teletransportación que genera el portal.

La lógica del submit se separa del return para mantener el componente limpio. Creamos una función onSubmit que previene la acción por defecto del formulario, llama a addTodo(newTodoValue) y luego cierra el modal con setOpenModal(false). La función onCancel simplemente cierra el modal, sin necesidad de cancelar nada extra.

¿Qué hace React.useContext? Devuelve el objeto con todas las propiedades compartidas por un Provider, permitiendo que cualquier componente acceda al estado global sin pasar props manualmente.

¿Por qué usar estado local en lugar de global para un input?

No todo necesita vivir en el contexto. Para el texto que el usuario escribe en el textarea creamos un estado local con React.useState(''), llamado newTodoValue y su actualizador setNewTodoValue [02:44].

La razón es simple: el contexto no necesita saber letra por letra lo que escribe el usuario en tiempo real. Solo necesita el valor final cuando se confirma la acción con el botón añadir. Esto evita renders innecesarios en toda la aplicación.

El textarea se vincula con dos propiedades:

  • value={newTodoValue} para mostrar siempre el estado actual.
  • onChange={onChange} que ejecuta setNewTodoValue(event.target.value) en cada tecla.

¿Cuándo usar estado local vs global? Usa estado local cuando la información solo le importa a un componente, como el texto que se está escribiendo. Usa estado global cuando varios componentes necesitan leer o modificar el mismo dato.

¿Cómo implementar la función addTodo en el contexto?

La función addTodo vive dentro del TodoContext y se apoya en saveTodos, que viene del custom hook useLocalStorage. Este hook ya se encarga de persistir los datos tanto en estado como en local storage [06:12].

La lógica reutiliza el patrón de completeTodo:

  1. Crear una copia del array de todos con const newTodos = [...todos].
  2. Agregar el nuevo elemento con newTodos.push({ text, completed: false }).
  3. Llamar a saveTodos(newTodos) para actualizar estado y local storage.

El objeto del nuevo to-do tiene dos propiedades: el text recibido como parámetro y completed: false por defecto, porque toda tarea recién creada está pendiente.

¿Qué errores comunes aparecen al integrar el contexto?

Al probar la aplicación apareció el error Uncaught TypeError: addTodo is not a function. La causa fue olvidar exponer la función en la propiedad value del TodoContext.Provider. Cualquier función o estado que quieras consumir desde otro componente debe estar listada ahí, junto a completeTodo y deleteTodo.

Otro ajuste fue cambiar el estado inicial de openModal de true a false, para que el modal aparezca cerrado al cargar la página.

¿Qué se logra al combinar Context API, portales y local storage?

La aplicación final responde a todas las interacciones del usuario: completar, eliminar, filtrar y crear tareas. Los datos persisten al recargar gracias al local storage, los estados de carga y error mejoran la experiencia, y el prop drilling desaparece al centralizar la información en un contexto global.

Incluso con un modal renderizado vía portal en otro punto del DOM, el componente sigue comunicándose con el contexto sin fricción. El siguiente paso natural es hacer el deploy con GitHub Pages para compartir el proyecto.

¿Tu addTodo ya funciona o te apareció algún error distinto? Cuéntalo en los comentarios.