Când gestionați stări complexe într-o aplicație Next, lucrurile pot deveni dificile rapid. Cârlige tradiționale ca useState ajutor cu conducerea statului, dar prezintă o problemă de foraj cu prop. Forarea cu prop înseamnă transmiterea datelor sau funcțiilor prin mai multe componente.

O abordare mai bună ar fi separarea logicii dvs. de gestionare a stării de componente și actualizarea acestor stări de oriunde în aplicația dvs. Vă vom prezenta cum să utilizați Context API în timp ce construim o aplicație simplă pentru lista de activități.

Înainte de a începe lista de sarcini

Înainte de a putea crea aplicația pentru lista de activități, veți avea nevoie de:

  • Cunoștințe de bază despre operatori JavaScript moderni și Cârligul useState al lui React.
  • O înțelegere a cum să destructurați tablouri și obiecte în JavaScript.
  • Nodul v16.8 sau o versiune ulterioară instalată pe mașina dvs. locală și familiaritate cu manageri de pachete precum npm sau fire.

Puteți găsi proiectul finalizat pe GitHub pentru referință și explorare ulterioară.

instagram viewer

Înțelegerea stării și managementului aplicației

Starea aplicației se referă la starea curentă a unei aplicații la un moment dat. Acestea includ informații pe care aplicația le cunoaște și le gestionează, cum ar fi introducerea utilizatorului și datele preluate dintr-o bază de date sau dintr-o API (Interfață de programare a aplicației).

Pentru a înțelege starea aplicației, luați în considerare stările posibile ale unei simple aplicații de contor. Ei includ:

  • Starea implicită când contorul este la zero.
  • O stare crescută când contorul crește cu unu.
  • O stare scăzută când contorul reduce cu unu.
  • O stare de resetare când contorul revine la starea implicită.

O componentă React se poate abona la modificări de stare. Când un utilizator interacționează cu o astfel de componentă, acțiunile sale, cum ar fi clicurile pe buton, pot gestiona actualizările stării.

Acest fragment arată o aplicație de contor simplă, în starea sa implicită, care gestionează starea pe baza acțiunilor de clic:

const [contor, setCounter] = useState(0);

întoarcere (


{contra}</h1>

Configurare și instalare

Depozitul proiectului conține două ramuri: incepator și context. Puteți folosi ramura de pornire ca bază pentru a construi proiectul din sau ramura de context pentru a previzualiza demonstrația finală.

Clonarea aplicației Starter

Aplicația de pornire oferă UI de care veți avea nevoie pentru aplicația finală, astfel încât să vă puteți concentra pe implementarea logicii de bază. Deschideți un terminal și rulați următoarea comandă pentru a clona ramura de pornire a depozitului pe mașina dvs. locală:

git clonare -b starter https://github.com/makeuseofcode/Next.js-CRUD-todo-app.git

Rulați următoarea comandă, în directorul proiectului, pentru a instala dependențele și a porni serverul de dezvoltare:

yarn && yarn dev

Sau:

npm i && npm rulați dev

Dacă totul a mers bine, interfața de utilizare ar trebui să se afișeze în browser:

Implementarea logicii

API-ul Context oferă o modalitate de a gestiona și partaja datele de stare între componente, fără a fi nevoie de forarea manuală a suportului.

Pasul 1: Creați și exportați context

Creeaza o src/app/context folder pentru a stoca fișierul de context și pentru a menține directorul de proiect bine organizat. În acest folder, creați un todo.context.jsx fișier care va conține toată logica de context pentru aplicație.

Importă createContext funcția de la reacţiona bibliotecă și apelați-o, stocând rezultatul într-o variabilă:

import { createContext} din"reacţiona";
const TodoContext = createContext();

Apoi, creați un personalizat foloseșteTodoContext cârlig care se întoarce TodoContext în forma sa utilizabilă.

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

Pasul 2: Creați și gestionați statele

Pentru a efectua acțiunile CRUD (Creare, Read, Update, Delete) ale aplicației, va trebui să creați stările și să le gestionați cu ajutorul Furnizor componentă.

const TodoContextProvider = ({copii}) => {
const [sarcină, setTask] = useState("");
const [sarcini, setTasks] = useState([]);
întoarcere<TodoContext. Furnizorvaloare={{}}>{copii}TodoContext. Furnizor>;
};

exportMod implicit TodoContextProvider;

Chiar înainte de întoarcere declarație, creați a handleTodoInput funcție care va rula atunci când utilizatorul introduce o activitate de făcut. Această funcție actualizează apoi sarcină stat.

const handleTodoInput = (intrare) => setTask (intrare);

Adauga o createTask funcție care va rula atunci când un utilizator trimite o activitate de făcut. Această funcție actualizează sarcini stare și atribuie noii sarcini un ID aleator.

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

setTasks([
{
id: Matematică.trunc(Matematică.Aleatoriu() * 1000 + 1),
sarcină,
},
...sarcini,
]);
};

Creaza un updateTask funcția care mapează prin sarcini listează și actualizează sarcina al cărei ID se potrivește cu ID-ul sarcinii pe care s-a făcut clic.

const updateTask = (id, updateText) =>
setTasks (tasks.map((t) => (id-ul? { ...t, sarcină: updateText }: t)));

Creeaza o deleteTask funcția care actualizează sarcini listă astfel încât să includă toate sarcinile al căror ID nu se potrivește cu parametrul dat.

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

Pasul 3: Adăugați state și handler la furnizor

Acum ați creat stările și ați scris codul pentru a le gestiona, trebuie să faceți aceste stări și funcții de gestionare disponibile pentru Furnizor. Le puteți furniza sub formă de obiect, folosind valoare proprietatea Furnizor componentă.

întoarcere (
valoare={{
sarcină,
sarcini,
handleTodoInput,
createTask,
updateTask,
deleteTask,
}}
>
{copii}
</TodoContext.Provider>
);

Pasul 4: Scopul contextului

The Furnizor pe care ați creat-o trebuie să împacheteze componenta de nivel superior pentru a face contextul disponibil pentru întreaga aplicație. Pentru a face acest lucru, editați src/app/page.jsx și înfășurați Todos componentă cu TodoContextProvider componenta:


;
</TodoContextProvider>;

Pasul 5: Utilizați contextul din Componente

Editează-ți src/app/components/Todos.jsx file și destructura sarcini, sarcină, handleTodoInput, și createTask printr-un apel către foloseșteTodoContext funcţie.

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

Acum, actualizați elementul de formular pentru a gestiona evenimentul de trimitere și modificările la câmpul principal de intrare:

createTask (e)}>
"todo-input" tip="text" substituent=„Introduceți o sarcină” valoare necesară={sarcină} onChange={(e) => handleTodoInput (e.target.value)} />
"trimite-te" tip="Trimite" valoare=„Adăugați sarcină” />
</form>

Pasul 6: Redați sarcinile în UI

Acum puteți utiliza aplicația pentru a crea și adăuga o sarcină la sarcini listă. Pentru a actualiza afișajul, va trebui să mapați prin cele existente sarcini și redați-le în UI. Mai întâi, creați un src/app/components/Todo.jsx componentă pentru a deține un singur lucru de făcut.

În cadrul src/app/components/Todo.jsx component, editați sau ștergeți o sarcină invocând updateTask și deleteTask funcții în care le-am creat src/app/context/todo.context.jsx fişier.

import Reacționează, { useState } din"reacţiona";
import { useTodoContext } din„../context/todo.context”;

const Todo = ({ sarcină }) => {
const { updateTask, deleteTask } = useTodoContext();

// starea isEdit urmărește când o sarcină este în modul de editare
const [isEdit, setIsEdit] = useState(fals);

întoarcere (

"todo-wrapper">


{este Editare? ( <intraretip="text"valoare={sarcină.sarcină}
onChange={(e) => updateTask (task.id, e.target.value)} /> ):
(<thnumele clasei="sarcină">{sarcină.sarcină}th> )}
"acțiuni">

exportMod implicit A face;

Pentru a reda src/app/components/Todo.jsx componentă pentru fiecare sarcină, intră în src/app/components/Todos.jsx fișier și mapare condiționat prin intermediul sarcini imediat după antet eticheta de inchidere.

{sarcini && (

{tasks.map((sarcina, i) => ( <A facecheie={i}sarcină={sarcină} /> ))}
</main>
)}

Testați aplicația dvs. într-un browser și confirmați că dă rezultatul așteptat.

Salvarea sarcinilor în stocarea locală

În prezent, reîmprospătarea paginii va reseta sarcinile, eliminând toate pe care le-ați creat. O modalitate de a remedia această problemă este prin stocarea sarcinilor în stocarea locală a browserului.

API-ul de stocare web este o îmbunătățire a stocării cookie-urilor, cu funcții care îmbunătățesc experiența atât pentru utilizatori, cât și pentru dezvoltatori.