Al administrar estados complejos en una aplicación Next, las cosas pueden complicarse rápidamente. Anzuelos tradicionales como useState ayuda con la gestión estatal, pero presentan un problema de perforación puntal. Prop Drilling significa pasar datos o funciones a través de varios componentes.

Un mejor enfoque sería separar la lógica de administración de su estado de los componentes y actualizar estos estados desde cualquier lugar de su aplicación. Lo guiaremos a través de cómo usar la API de contexto a medida que construimos una aplicación de lista de tareas simple.

Antes de comenzar su lista de tareas pendientes

Antes de que pueda crear la aplicación de la lista de tareas pendientes, necesitará:

  • Conocimiento básico de operadores modernos de JavaScript y Gancho useState de React.
  • Una comprensión de cómo desestructurar matrices y objetos en JavaScript.
  • Nodo v16.8 o posterior instalado en su máquina local y familiaridad con administradores de paquetes como npm o hilo.

Puedes encontrar el proyecto terminado en GitHub para referencia y mayor exploración.

instagram viewer

Comprensión del estado y la gestión de la aplicación

El estado de la aplicación se refiere a la condición actual de una aplicación en un momento determinado. Esto incluye información que la aplicación conoce y administra, como la entrada del usuario y los datos obtenidos de una base de datos o una API (interfaz de programación de aplicaciones).

Para comprender el estado de la aplicación, considere los posibles estados de una simple aplicación de contador. Incluyen:

  • El estado predeterminado cuando el contador está en cero.
  • Un estado aumentado cuando el contador aumenta en uno.
  • Un estado disminuido cuando el contador se reduce en uno.
  • Un estado de reinicio cuando el contador vuelve a su estado predeterminado.

Un componente de React puede suscribirse a cambios de estado. Cuando un usuario interactúa con dicho componente, sus acciones, como hacer clic en un botón, pueden administrar las actualizaciones del estado.

Este fragmento muestra una aplicación de contador simple, en su estado predeterminado, que administra el estado en función de las acciones de clic:

constante [contador, establecerContador] = usarEstado(0);

devolver (


{contador}</h1>

Configuración e instalación

El repositorio del proyecto contiene dos ramas: inicio y contexto. Puede usar la rama de inicio como base para construir el proyecto o la rama de contexto para obtener una vista previa de la demostración final.

Clonación de la aplicación de inicio

La aplicación de inicio proporciona la interfaz de usuario que necesitará para la aplicación final, de modo que pueda concentrarse en la implementación de la lógica principal. Abra una terminal y ejecute el siguiente comando para clonar la rama inicial del repositorio en su máquina local:

git clon -b arrancador https://github.com/makeuseofcode/Next.js-CRUD-todo-app.git

Ejecute el siguiente comando, dentro del directorio del proyecto, para instalar las dependencias e iniciar su servidor de desarrollo:

hilo y desarrollo de hilo

O:

npm i && npm ejecutar dev

Si todo salió bien, la interfaz de usuario debería mostrarse en su navegador:

Implementando la lógica

La API de contexto proporciona una forma de administrar y compartir datos de estado entre componentes, sin necesidad de realizar perforaciones manuales.

Paso 1: crear y exportar contexto

Crear un src/aplicación/contexto carpeta para almacenar el archivo de contexto y mantener el directorio del proyecto bien organizado. Dentro de esta carpeta, cree un todo.contexto.jsx archivo que contendrá toda la lógica de contexto para la aplicación.

Importar el crearContexto función de la reaccionar biblioteca y llamarlo, almacenando el resultado en una variable:

importar { crearContexto} de"reaccionar";
constante TodoContexto = crearContexto();

A continuación, cree un personalizado usarTodoContexto anzuelo que vuelve TodoContexto en su forma utilizable.

exportarconstante usarTodoContexto = () => useContext (TodoContexto);

Paso 2: crear y administrar estados

Para realizar las acciones CRUD (Crear, Leer, Actualizar, Eliminar) de la aplicación, deberá crear los estados y administrarlos con el Proveedor componente.

constante TodoContextProvider = ({ niños }) => {
constante [tarea, establecerTarea] = usarEstado("");
constante [tareas, establecerTareas] = useState([]);
devolver<TodoContexto. Proveedorvalor={{}}>{niños}TodoContexto. Proveedor>;
};

exportarpor defecto TodoContextProvider;

Justo antes de la devolver declaración, cree una manejarTodoInput función que se ejecutará cuando el usuario escriba una tarea pendiente. Esta función luego actualiza la tarea estado.

constante manejarTodoEntrada = (aporte) => establecerTarea (entrada);

Agrega un creartarea función que se ejecutará cuando un usuario envíe una tarea pendiente. Esta función actualiza la tareas state y asigna a la nueva tarea un ID aleatorio.

constante crearTarea = (mi) => {
e.preventDefault();

establecerTareas([
{
identificación: Matemáticas.trunc(Matemáticas.aleatorio() * 1000 + 1),
tarea,
},
...tareas,
]);
};

Crear un actualizarTarea función que mapea a través de la tareas list y actualiza la tarea cuyo ID coincide con el ID de la tarea en la que se hizo clic.

constante actualizarTarea = (id, actualizar texto) =>
setTareas (tareas.mapa((t) => (t.id id? { ...t, tarea: actualizarTexto }: t)));

Crear un borrar tarea función que actualiza la tareas list para que incluya todas las tareas cuyo ID no coincida con el parámetro dado.

constante eliminarTarea = (identificación) => setTasks (tareas.filtro((t) => t.id !== id));

Paso 3: agregue estados y controladores al proveedor

Ahora que ha creado los estados y el código escrito para administrarlos, debe hacer que estos estados y las funciones del controlador estén disponibles para el Proveedor. Puede suministrarlos en forma de un objeto, utilizando el valor propiedad de la Proveedor componente.

devolver (
valor={{
tarea,
tareas,
manejarTodoEntrada,
crear tarea,
actualizar tarea,
borrar tarea,
}}
>
{niños}
</TodoContext.Provider>
);

Paso 4: alcance el contexto

El Proveedor que ha creado debe ajustar el componente de nivel superior para que el contexto esté disponible para toda la aplicación. Para hacer esto, edite src/aplicación/página.jsx y envuelve el Todos componente con el TodoContextProvider componente:


;
</TodoContextProvider>;

Paso 5: use el contexto en los componentes

Edita tu src/app/components/Todos.jsx archivar y desestructurar tareas, tarea, manejarTodoInput, y creartarea a través de una llamada al usarTodoContexto función.

constante { tarea, tareas, handleTodoInput, createTask } = useTodoContext();

Ahora, actualice el elemento de formulario para manejar el evento de envío y los cambios en el campo de entrada principal:

crearTarea (e)}>
"entrada pendiente" tipo ="texto" marcador de posición ="Introduce una tarea" valor requerido={tarea} onChange={(e) => handleTodoInput (e.target.value)} />
"enviar-todo" tipo ="entregar" valor="Agregar tarea" />
</form>

Paso 6: renderizar tareas en la interfaz de usuario

Ahora puede usar la aplicación para crear y agregar una tarea al tareas lista. Para actualizar la pantalla, deberá mapear a través de existentes tareas y representarlos en la interfaz de usuario. Primero, crea un src/app/components/Todo.jsx componente para contener un único elemento de tarea pendiente.

Dentro de src/app/components/Todo.jsx componente, edite o elimine una tarea invocando el actualizarTarea y borrar tarea funciones que creamos en src/app/context/todo.context.jsx archivo.

importar Reaccionar, { estado de uso } de"reaccionar";
importar { usarTodoContexto } de"../contexto/todo.contexto";

constante Todo = ({ tarea }) => {
constante { actualizarTarea, eliminarTarea } = usarTodoContexto();

// isEdit rastrea el estado cuando una tarea está en modo de edición
constante [esEditar, establecerEsEditar] = usarEstado(FALSO);

devolver (

"todo-envoltura">


{esEditar? ( <aportetipo="texto"valor={tarea.tarea}
onChange={(e) => updateTask (task.id, e.target.value)} /> ) :
(<elnombre de la clase="tarea">{tarea.tarea}el> )}
"comportamiento">

exportarpor defecto Hacer;

para hacer el src/app/components/Todo.jsx componente para cada tarea, entra en el src/app/components/Todos.jsx archivar y mapear condicionalmente a través del tareas justo después de la encabezamiento etiqueta de cierre.

{tareas && (

{tareas.mapa((tarea, yo) => ( <Hacerllave={i}tarea={tarea} /> ))}
</main>
)}

Pruebe su aplicación en un navegador y confirme que da el resultado esperado.

Guardar tareas en el almacenamiento local

Actualmente, actualizar la página restablecerá las tareas y descartará las que haya creado. Una forma de solucionar este problema es almacenar las tareas en el almacenamiento local del navegador.

La API de almacenamiento web es una mejora en el almacenamiento de cookies, con características que mejoran la experiencia tanto para los usuarios como para los desarrolladores.