Quando si gestiscono stati complessi in un'applicazione Next, le cose possono diventare complicate rapidamente. Ganci tradizionali come useState aiuto con la gestione statale ma presenta un problema di perforazione dell'elica. Prop drilling significa passare dati o funzioni attraverso diversi componenti.

Un approccio migliore sarebbe separare la logica di gestione dello stato dai componenti e aggiornare questi stati da qualsiasi punto dell'applicazione. Ti guideremo attraverso come utilizzare l'API Context mentre creiamo una semplice applicazione per l'elenco delle cose da fare.

Prima di iniziare la tua lista di cose da fare

Prima di poter creare l'applicazione dell'elenco delle cose da fare, avrai bisogno di:

  • Conoscenza di base di moderni operatori JavaScript E L'hook useState di React.
  • Una comprensione di come destrutturare array e oggetti in JavaScript.
  • Nodo v16.8 o successiva installata sul computer locale e familiarità con gestori di pacchetti come npm o filato.

Puoi trovare il progetto finito su Git Hub per riferimento e ulteriori esplorazioni.

instagram viewer

Comprensione dello stato e della gestione dell'applicazione

Lo stato dell'applicazione si riferisce alla condizione corrente di un'applicazione in un determinato momento. Ciò include le informazioni che l'app conosce e gestisce, come l'input dell'utente e i dati recuperati da un database o un'API (Application Programming Interface).

Per comprendere lo stato dell'applicazione, considerare i possibili stati di una semplice applicazione contatore. Loro includono:

  • Lo stato predefinito quando il contatore è a zero.
  • Uno stato aumentato quando il contatore aumenta di uno.
  • Uno stato diminuito quando il contatore si riduce di uno.
  • Uno stato di ripristino quando il contatore torna allo stato predefinito.

Un componente React può iscriversi ai cambiamenti di stato. Quando un utente interagisce con tale componente, le sue azioni, come i clic sui pulsanti, possono gestire gli aggiornamenti allo stato.

Questo frammento mostra una semplice applicazione contatore, nel suo stato predefinito, che gestisce lo stato in base alle azioni di clic:

cost [contatore, impostaContatore] = useState(0);

ritorno (


{contatore}</h1>

Configurazione e installazione

Il repository del progetto contiene due rami: antipasto E contesto. È possibile utilizzare il ramo di avviamento come base per creare il progetto o il ramo di contesto per visualizzare in anteprima la demo finale.

Clonazione dell'app iniziale

L'app iniziale fornisce l'interfaccia utente di cui avrai bisogno per l'app finale, così puoi concentrarti sull'implementazione della logica di base. Apri un terminale ed esegui il seguente comando per clonare il ramo iniziale del repository sul tuo computer locale:

idiota clone -b antipasto https://github.com/makeuseofcode/Next.js-CRUD-todo-app.git

Esegui il seguente comando, all'interno della directory del progetto, per installare le dipendenze e avviare il tuo server di sviluppo:

filato && sviluppo filato

O:

npm i && npm esegue dev

Se tutto è andato bene, l'interfaccia utente dovrebbe visualizzare nel tuo browser:

Implementazione della logica

L'API Context fornisce un modo per gestire e condividere i dati di stato tra i componenti, senza la necessità di perforazione manuale dell'elica.

Passaggio 1: creazione ed esportazione del contesto

Creare un src/app/contesto cartella per archiviare il file di contesto e mantenere la directory del progetto ben organizzata. All'interno di questa cartella, crea un file todo.context.jsx file che conterrà tutta la logica di contesto per l'applicazione.

Importa il createContext funzione dal reagire library e chiamala, memorizzando il risultato in una variabile:

importare {creareContesto} da"reagire";
cost TodoContext = createContext();

Quindi, crea un file personalizzato useTodoContext gancio che ritorna TodoContext nella sua forma utilizzabile.

esportarecost useTodoContext = () => useContext(TodoContext);

Passaggio 2: creazione e gestione degli stati

Per eseguire le azioni CRUD (Create, Read, Update, Delete) dell'applicazione è necessario creare gli stati e gestirli con il Fornitore componente.

cost TodoContextProvider = ({ bambini }) => {
cost [attività, setTask] = useState("");
cost [tasks, setTasks] = useState([]);
ritorno<TodoContext. Fornitorevalore={{}}>{bambini}TodoContext. Fornitore>;
};

esportarepredefinito TodoContextProvider;

Poco prima del ritorno dichiarazione, creare un handleTodoInput funzione che verrà eseguita quando l'utente digita una cosa da fare. Questa funzione quindi aggiorna il file compito stato.

cost handleTodoInput = (ingresso) => setTask (ingresso);

Aggiungere un createTask funzione che verrà eseguita quando un utente invia una cosa da fare. Questa funzione aggiorna il file compiti stato e assegna alla nuova attività un ID casuale.

cost createTask = (e) => {
e.preventDefault();

setTask([
{
id: Matematica.trunc(Matematica.casuale() * 1000 + 1),
compito,
},
...compiti,
]);
};

Creare un updateTask funzione che mappa attraverso il compiti elenca e aggiorna l'attività il cui ID corrisponde all'ID dell'attività selezionata.

cost updateTask = (id, updateText) =>
setTasks (attività.map((T) => (t.id id? { ...T, compito: updateText }: t)));

Creare un deleteTask funzione che aggiorna il compiti list in modo che includa tutte le attività il cui ID non corrisponde al parametro specificato.

cost deleteTask = (id) => setTasks (tasks.filter((T) => t.id !== id));

Passaggio 3: aggiungere stati e gestori al provider

Ora che hai creato gli stati e scritto il codice per gestirli, devi rendere questi stati e le funzioni del gestore disponibili per il Fornitore. Puoi fornirli sotto forma di oggetto, utilizzando il file valore proprietà del Fornitore componente.

ritorno (
valore={{
compito,
compiti,
handleTodoInput,
creareattività,
aggiornamentoattività,
deleteTask,
}}
>
{bambini}
</TodoContext.Provider>
);

Passaggio 4: ambito del contesto

IL Fornitore creato deve eseguire il wrapping del componente di primo livello per rendere disponibile il contesto all'intera applicazione. Per fare ciò, modifica src/app/page.jsx e avvolgere il Tutto componente con il TodoContextProvider componente:


;
</TodoContextProvider>;

Passaggio 5: utilizzare il contesto nei componenti

Modifica il tuo src/app/components/Todos.jsx archiviare e destrutturare compiti, compito, handleTodoInput, E createTask tramite una chiamata al useTodoContext funzione.

cost { attività, attività, handleTodoInput, createTask } = useTodoContext();

Ora aggiorna l'elemento del modulo per gestire l'evento di invio e le modifiche al campo di input principale:

createTask (e)}>
"todo-input" tipo="testo" segnaposto="Inserisci un'attività" valore richiesto={task} onChange={(e) => handleTodoInput (e.target.value)} />
"invia-da fare" tipo="invia" valore="Aggiungi attività" />
</form>

Passaggio 6: eseguire il rendering delle attività nell'interfaccia utente

Ora puoi utilizzare l'app per creare e aggiungere un'attività al file compiti elenco. Per aggiornare il display, dovrai eseguire la mappatura attraverso l'esistente compiti e renderli nell'interfaccia utente. Per prima cosa, crea un file src/app/components/Todo.jsx componente per contenere un singolo elemento attività.

All'interno del src/app/components/Todo.jsx componente, modificare o eliminare un'attività richiamando il updateTask E deleteTask funzioni che abbiamo creato in src/app/context/todo.context.jsx file.

importare Reagisci, { useState } da"reagire";
importare { useTodoContext } da"../contesto/todo.context";

cost Tutto = ({ compito }) => {
cost { updateTask, deleteTask } = useTodoContext();

// lo stato isEdit tiene traccia quando un'attività è in modalità di modifica
cost [isEdit, setIsEdit] = useState(falso);

ritorno (

"todo-wrapper">


{èModifica? ( <ingressotipo="testo"valore={attività.attività}
onChange={(e) => updateTask (task.id, e.target.value)} /> ) :
(<thnome della classe="compito">{attività.attività}th> )}
"Azioni">

esportarepredefinito Fare;

Per rendere il src/app/components/Todo.jsx componente per ciascuno compito, entra nel src/app/components/Todos.jsx file e mappare in modo condizionale attraverso il file compiti subito dopo il intestazione cartellino di chiusura.

{compiti && (

{attività.mappa((compito, i) => ( <Farechiave={io}compito={compito} /> ))}
</main>
)}

Prova la tua applicazione in un browser e conferma che fornisce il risultato previsto.

Salvataggio delle attività nell'archivio locale

Attualmente, l'aggiornamento della pagina ripristinerà le attività, scartando quelle che hai creato. Un modo per risolvere questo problema è archiviare le attività nella memoria locale del browser.

L'API di archiviazione Web è un miglioramento dell'archiviazione dei cookie, con funzionalità che migliorano l'esperienza sia per gli utenti che per gli sviluppatori.