När du hanterar komplexa tillstånd i en Next-applikation kan saker snabbt bli knepiga. Traditionella krokar som useState stöd med statlig ledning men presentera en fråga om propellborrning. Stödborrning innebär att skicka data eller funktioner ner genom flera komponenter.

Ett bättre tillvägagångssätt skulle vara att separera din tillståndshanteringslogik från komponenterna och uppdatera dessa tillstånd var som helst i din applikation. Vi går igenom hur du använder Context API när vi bygger en enkel att göra-lista-applikation.

Innan du börjar din att-göra-lista

Innan du kan bygga att-göra-listan behöver du:

  • Grundläggande kunskap om moderna JavaScript-operatörer och Reacts useState-krok.
  • En förståelse för hur man destrukturera arrayer och objekt i JavaScript.
  • Nod v16.8 eller senare installerad på din lokala dator och bekantskap med pakethanterare som npm eller garn.

Du hittar det färdiga projektet på GitHub för referens och vidare utforskning.

Förstå applikationstillstånd och hantering

Applikationsstatus avser det aktuella tillståndet för en applikation vid en given tidpunkt. Detta inkluderar information som appen känner till och hanterar, såsom användarinmatning och data hämtade från en databas eller ett API (Application Programming Interface).

instagram viewer

För att förstå tillämpningens tillstånd, överväg de möjliga tillstånden för en enkel motapplikation. De inkluderar:

  • Standardtillståndet när räknaren står på noll.
  • Ett ökat tillstånd när räknaren ökar med ett.
  • Ett minskat tillstånd när räknaren minskar med ett.
  • Ett återställningstillstånd när räknaren återgår till standardläge.

En React-komponent kan prenumerera på förändringar i tillstånd. När en användare interagerar med en sådan komponent kan deras åtgärder – som knappklickningar – hantera uppdateringar av tillståndet.

Det här utdraget visar ett enkelt motprogram, i dess standardläge, som hanterar tillstånd baserat på klickåtgärder:

konst [räknare, setCounter] = useState(0);

lämna tillbaka (


{counter}</h1>

Installation och installation

Projektets arkiv innehåller två grenar: förrätt och sammanhang. Du kan använda startgrenen som bas för att bygga projektet från eller kontextgrenen för att förhandsgranska den slutliga demon.

Kloning av Starter-appen

Startappen tillhandahåller det användargränssnitt du behöver för den slutliga appen, så att du kan fokusera på implementeringen av kärnlogiken. Öppna en terminal och kör följande kommando för att klona startgrenen av förvaret till din lokala dator:

git klona -b förrätt https://github.com/makeuseofcode/Next.js-CRUD-todo-app.git

Kör följande kommando, i projektkatalogen, för att installera beroenden och starta din utvecklingsserver:

garn && garn dev

Eller:

npm i && npm kör dev

Om allt gick bra bör användargränssnittet visas i din webbläsare:

Implementering av logiken

Context API ger ett sätt att hantera och dela tillståndsdata mellan komponenter, utan att behöva manuell propborrning.

Steg 1: Skapa och exportera sammanhang

Skapa en src/app/context mapp för att lagra kontextfilen och hålla projektkatalogen välorganiserad. I den här mappen skapar du en todo.context.jsx fil som kommer att innehålla all kontextlogik för applikationen.

Importera skapaKontext funktion från reagera bibliotek och kalla det, lagra resultatet i en variabel:

importera { createContext} från"reagera";
konst TodoContext = createContext();

Skapa sedan en anpassad använd TodoContext krok som återvänder TodoContext i dess användbara form.

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

Steg 2: Skapa och hantera tillstånd

För att utföra programmets CRUD-åtgärder (Create, Read, Update, Delete) måste du skapa tillstånden och hantera dem med Leverantör komponent.

konst TodoContextProvider = ({ barn }) => {
konst [task, setTask] = useState("");
konst [tasks, setTasks] = useState([]);
lämna tillbaka<TodoContext. Leverantörvärde={{}}>{barn}TodoContext. Leverantör>;
};

exporterastandard TodoContextProvider;

Strax före lämna tillbaka uttalande, skapa ett hantera TodoInput funktion som körs när användaren skriver in en att göra. Denna funktion uppdaterar sedan uppgift stat.

konst handleTodoInput = (inmatning) => setTask (ingång);

Lägg till en skapaTask funktion som körs när en användare skickar en att göra. Denna funktion uppdaterar uppgifter och tilldelar den nya uppgiften ett slumpmässigt ID.

konst skapaTask = (e) => {
e.preventDefault();

setTasks([
{
id: Matematik.trunc(Matematik.random() * 1000 + 1),
uppgift,
},
...uppgifter,
]);
};

Skapa en uppdateraTask funktion som kartlägger genom uppgifter lista och uppdaterar uppgiften vars ID matchar ID för den klickade uppgiften.

konst updateTask = (id, updateText) =>
setTasks (tasks.map((t) => (t.id id? { ...t, uppgift: updateText }: t)));

Skapa en radera Task funktion som uppdaterar uppgifter lista så att den inkluderar alla uppgifter vars ID inte matchar den givna parametern.

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

Steg 3: Lägg till stater och hanterare till leverantören

Nu du har skapat tillstånden och skrivit kod för att hantera dem, måste du göra dessa tillstånd och hanterarfunktioner tillgängliga för Leverantör. Du kan tillhandahålla dem i form av ett objekt med hjälp av värde egendom av Leverantör komponent.

lämna tillbaka (
värde={{
uppgift,
uppgifter,
handleTodoInput,
skapaTask,
updateTask,
radera Task,
}}
>
{barn}
</TodoContext.Provider>
);

Steg 4: Omfattning av sammanhanget

De Leverantör du har skapat måste omsluta toppnivåkomponenten för att göra sammanhanget tillgängligt för hela programmet. För att göra detta, redigera src/app/page.jsx och linda in Todos komponent med TodoContextProvider komponent:


;
</TodoContextProvider>;

Steg 5: Använd kontexten i komponenter

Redigera din src/app/components/Todos.jsx fil och destrukturera uppgifter, uppgift, hantera TodoInput, och skapaTask via ett samtal till använd TodoContext fungera.

konst { task, tasks, handleTodoInput, createTask } = useTodoContext();

Uppdatera nu formulärelementet för att hantera inlämningshändelsen och ändringar i huvudinmatningsfältet:

skapaTask (e)}>
"att göra-ingång" typ="text" platshållare="Ange en uppgift" obligatoriskt värde={task} onChange={(e) => handleTodoInput (e.target.value)} />
"skicka in att göra" typ="Skicka in" värde="Lägg till uppgift" />
</form>

Steg 6: Rendera uppgifter i användargränssnittet

Du kan nu använda appen för att skapa och lägga till en uppgift till uppgifter lista. För att uppdatera displayen måste du kartlägga befintliga uppgifter och återge dem i användargränssnittet. Skapa först en src/app/components/Todo.jsx komponent för att hålla ett enda att göra-objekt.

Inom src/app/components/Todo.jsx komponent, redigera eller ta bort en uppgift genom att anropa uppdateraTask och radera Task funktioner vi skapade i src/app/context/todo.context.jsx fil.

importera Reagera, { useState } från"reagera";
importera { useTodoContext } från"../context/todo.context";

konst Att göra = ({ uppgift }) => {
konst { updateTask, deleteTask } = useTodoContext();

// isEdit-tillstånd spårar när en uppgift är i redigeringsläge
konst [isEdit, setIsEdit] = useState(falsk);

lämna tillbaka (

"todo-wrapper">


{är Redigera? ( <inmatningtyp="text"värde={task.task}
onChange={(e) => uppdateraTask (task.id, e.target.value)} /> ):
(<thklassnamn="uppgift">{task.task}th> )}
"handlingar">

exporterastandard Att göra;

För att återge src/app/components/Todo.jsx komponent för varje uppgift, gå in på src/app/components/Todos.jsx fil och villkorligt kartlägga genom uppgifter direkt efter rubrik avslutande tagg.

{uppgifter && (

{tasks.map((uppgift, dvs) => ( <Att göranyckel={i}uppgift={uppgift} /> ))}
</main>
)}

Testa din applikation i en webbläsare och bekräfta att den ger det förväntade resultatet.

Spara uppgifter i lokal lagring

För närvarande återställs uppgifterna om du uppdaterar sidan och alla som du har skapat förkastas. Ett sätt att lösa detta problem är att lagra uppgifterna i webbläsarens lokala lagring.

Web storage API är en förbättring av cookie-lagring, med funktioner som förbättrar upplevelsen för både användare och utvecklare.