Jak używać kontekstu React do zarządzania stanem w Next.js 13
Next.js oferuje kilka podejść do zarządzania stanem. Podczas gdy niektóre z tych metod wymagają instalowania nowych bibliotek, Context API Reacta jest wbudowane, więc jest to świetny sposób na zmniejszenie zewnętrznych zależności.
React Context pozwala na łatwe przesyłanie informacji w całej hierarchii komponentów, eliminując potrzebę inwazyjnego wiercenia w rekwizytach. Okazuje się to szczególnie korzystne w utrzymywaniu globalnie istotnych danych, takich jak status logowania aktualnie uwierzytelnionego użytkownika i jego ulubiony motyw.
Zrozumienie React Context API
Aby skutecznie zagłębić się w implementację kodu, kluczowe jest kompleksowe zrozumienie React Context API i jego celu w rozwiązywaniu konkretnych wyzwań.
Wykorzystanie rekwizytów umożliwia płynną transmisję informacji między połączonymi elementami, ułatwiając przesyłanie danych z nadrzędnego komponentu do jego podrzędnych odpowiedników poprzez hierarchiczną strukturę.
Metoda ta okazuje się korzystna, ponieważ jednoznacznie pokazuje konkretne komponenty, które polegają na określonych informacjach, wraz z późniejszym postępem takich danych w hierarchicznej strukturze komponentów.
Niemniej jednak mogą pojawić się trudności, gdy komponenty o skomplikowanym zagnieżdżeniu wymagają współdzielenia identycznych rekwizytów. Takie okoliczności mogą powodować komplikacje i potencjalnie prowadzić do zawiłego kodu, który jest trudniejszy do utrzymania. Wśród tych obaw, a także innych, są wady związane z wierceniem rekwizytów.
React Context zajmuje się kwestią dostępu do danych globalnych, oferując ujednolicone podejście do tworzenia i wykorzystywania informacji, które muszą być dostępne w różnych komponentach aplikacji.
Wykorzystanie ustrukturyzowanego kontenera danych ułatwia płynne pobieranie i manipulowanie informacjami przez różne komponenty systemu. W ten sposób zwiększa się wydajność organizacyjna, zapewniając optymalną funkcjonalność w złożonej sieci.
Kod źródłowy tego projektu znajduje się w naszym repozytorium GitHub, do którego mogą uzyskać dostęp zainteresowane strony.
Rozpoczęcie pracy z zarządzaniem stanami w Next.js 13 Korzystanie z React Context API
Komponenty serwera Next.js umożliwiają programistom tworzenie aplikacji, które płynnie integrują responsywność platform po stronie klienta ze wzrostem wydajności związanym z treścią renderowaną na serwerze, oferując w ten sposób doskonałe wrażenia użytkownika przy jednoczesnej optymalizacji wydajności.
Next.js w wersji 13 domyślnie zawiera komponenty serwera w katalogu aplikacji, co jest obecnie uważane za stabilne. Należy jednak zauważyć, że ponieważ wszystkie komponenty są renderowane po stronie serwera, mogą pojawić się problemy podczas próby integracji bibliotek lub interfejsów API po stronie klienta, takich jak React Context.
Jednym ze skutecznych rozwiązań zapobiegających temu problemowi jest użycie flagi “client”, którą można zastosować do plików JavaScript w celu wykonania kodu po stronie klienta.
Aby zainicjować proces, można utworzyć środowisko programistyczne Next.js 13 na komputerze lokalnym, wykonując następujące czynności w terminalu:
npx create-next-app@latest next-context-api
Aby uzyskać dostęp do katalogu nowo utworzonego projektu w wyrafinowany sposób, wykonaj następujące kroki:1. Po utworzeniu projektu przy użyciu odpowiedniej metodologii, przejdź do zlokalizowania jego fizycznej lokalizacji w systemie plików, nawigując po hierarchicznej strukturze katalogów i plików, aż dotrzesz do wyznaczonego folderu zawierającego wszystkie komponenty związane z projektem. Proces ten może obejmować wykorzystanie interfejsów wiersza poleceń lub graficznych interfejsów użytkownika w zależności od systemu operacyjnego i preferencji.
cd next-context-api
Następnie uruchom serwer deweloperski:
npm run dev
Po ustanowieniu podstawowej struktury projektu Next.js, można skonstruować podstawową aplikację menedżera zadań wykorzystującą React Context API jako główny sposób zarządzania stanem.
Tworzenie dostawcy kontekstu
Funkcja dostawcy kontekstu działa jako główne źródło, z którego różne komponenty czerpią niezbędne informacje globalne, umożliwiając im efektywną interakcję z otoczeniem.
Utwórz nowy plik o nazwie src/context/Todo.context.js
w katalogu projektu i wklej do niego następujący kod:javascriptimport { defineContext } from ‘vuex’;export default defineContext({id: ’todo’,state: () => ({todos: [],selectedTodo: null,isAllChecked: false,showForm: false,}),mutations: {setTodos(state, value) {state.todos = value;},addTodo(state, todo) {if (!state.todos.length) {return;} const updatedTodos = […state.todos
"use client"
import React, { createContext, useReducer } from "react";
const initialState = {
todos: [],
};
const reducer = (state, action) => {
switch (action.type) {
case "ADD_TODO":
return { ...state, todos: [...state.todos, action.payload] };
case "DELETE_TODO":
return { ...state, todos: state.todos.filter((todo, index) =>
index !== action.payload) };
case "EDIT_TODO":
const updatedTodos = state.todos.map((todo, index) =>
index === action.payload.index ? action.payload.newTodo : todo);
return { ...state, todos: updatedTodos };
default:
return state;
}
};
export const TodoContext = createContext({
state: initialState,
dispatch: () => null,
});
export const TodoContextProvider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<TodoContext.Provider value={{ state, dispatch }}>
{children}
</TodoContext.Provider>
);
};
Niniejsza konfiguracja ustanawia kontekstowy framework dla Reacta, określany jako “TodoContext”, który rozpoczyna się od pustej listy zadań jako początkowego stanu aplikacji.
Oprócz ustalenia stanu początkowego, ta konfiguracja kontekstu zawiera funkcję reduktora, która określa kilka typów akcji. Implementacja tych typów akcji spowoduje zmiany w stanie kontekstu w oparciu o wykonane operacje.Na przykład działania te mogą obejmować wstawianie, usuwanie lub modyfikowanie elementów do zrobienia w kontekście.
właściwość value
, która reprezentuje stan początkowy kontekstu, oraz właściwość reducer
, która wyznacza funkcję operacji redukcji.
Po przyjęciu TodoContext przez dany element, aktualny stan tego kontekstu jest możliwy do pobrania, wraz z możliwością propagowania sygnałów do zmiany jego dyspozycji.
Dodaj dostawcę kontekstu do aplikacji Next.js
Aby dostawca kontekstu był renderowany na najwyższym poziomie aplikacji Next.js, zapewniając, że wszystkie komponenty po stronie klienta mają do niego dostęp, konieczne jest uwzględnienie kontekstu w głównym komponencie układu aplikacji.
Aby wykonać to zadanie, należy uzyskać dostęp do pliku “src/app/layout.js” i zawrzeć węzły podrzędne w szablonie HTML, wykorzystując dostawcę kontekstu, jak pokazano poniżej:
import './globals.css';
import { TodoContextProvider } from "@/context/Todo.context";
export const metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children
}) {
return (
<html lang="en">
<body>
<TodoContextProvider>{children}</TodoContextProvider>
</body>
</html>
);
}
Create a To-Do Component
Aby utworzyć nowy plik w określonej strukturze katalogów, wykonaj następujące kroki:1. Otwórz preferowany edytor tekstu lub zintegrowane środowisko programistyczne (IDE).2. Przejdź do folderu “src” projektu.3. w folderze “src” projektu.W folderze “src” zlokalizuj i wybierz podfolder “components”.4. Kliknij przycisk “New File” w edytorze tekstu lub IDE, aby wygenerować nowy pusty dokument.5. Zapisz nowo utworzony plik pod nazwą “Todo.js”. Należy to zrobić zarówno w podfolderze “components”, jak i w ogólnym folderze “src”.6. Po zapisaniu pliku można przystąpić do kopiowania i wklejania dostarczonego fragmentu kodu do nowego pliku “Todo.js”. Upewnij się, że wcięcie
Włącz niezbędne instrukcje importu, w tym flagę use client
, i oznacz ten komponent jako komponent po stronie klienta, wykorzystując odpowiednie flagi w poniższym fragmencie kodu:javascriptimport { use client } from ’next/client’;const MyComponent = () => {const [data, setData] = useState([]);// Użyj tutaj flagi klienta… return ( {/* Your component’s JSX goes here */} );};export default MyComponent;
"use client"
import { TodoContext } from "@/context/Todo.context";
import React, { useContext, useState } from "react";
Następnie określimy funkcjonalny aspekt naszej aplikacji, określając komponenty HTML, które mają być renderowane w przeglądarce internetowej przy użyciu JavaScript Extensible Markup Language (JSX).
export default function Todo() {
return (
<div style={{ marginBottom: "4rem", textAlign: "center" }}>
<h2>Todos</h2>
<input
type="text"
value={todoText}
onChange={(e) => setTodoText(e.target.value)}
style={{ marginBottom: 16}}
placeholder="Enter a todo"
/>
<button onClick={handleAddTodo}>Add Todo</button>
<ul>
{state.todos.map((todo, index) => (
<li key={index}>
{index === editingIndex ? (
<>
<input
type="text"
value={editedTodo}
onChange={(e) => setEditedTodo(e.target.value)}
/>
<button
style={{ marginRight: 16}}
onClick={() => handleEditTodo(index, editedTodo)}
>
Save
</button>
</>
) : (
<>
{todo}
<button
style={{ marginRight: 16}}
onClick={() => setEditingIndex(index)}
>Edit</button>
<button
onClick={() => handleDeleteTodo(index)}
>Delete</button>
</>
)}
</li>
))}
</ul>
</div>
);
}
Ten funkcjonalny komponent obejmuje interaktywne elementy do dodawania, modyfikowania i usuwania zadań na liście.Komponenty te są konstruowane przy użyciu możliwości renderowania warunkowego Reacta, które wyświetlają przyciski edycji i usuwania w zależności od bieżącej wartości zmiennej indeksującej.
Na koniec należy określić niezbędne zmienne stanu i zaimplementować odpowiednie funkcje obsługi dla każdego typu akcji w ciele komponentu funkcjonalnego. Aby to osiągnąć, należy dołączyć następujące linie kodu.
const { state, dispatch } = useContext(TodoContext);
const [todoText, setTodoText] = useState("");
const [editingIndex, setEditingIndex] = useState(-1);
const [editedTodo, setEditedTodo] = useState("");
const handleAddTodo = () => {
if (todoText.trim() !== "") {
dispatch({ type: "ADD_TODO", payload: todoText });
setTodoText("");
}
};
const handleDeleteTodo = (index) => {
dispatch({ type: "DELETE_TODO", payload: index });
};
const handleEditTodo = (index, newTodo) => {
dispatch({ type: "EDIT_TODO", payload: { index, newTodo } });
setEditingIndex(-1);
setEditedTodo("");
};
Wyżej wymienione obowiązki funkcjonalne obejmują zarządzanie zadaniami użytkownika w ramach stanu kontekstu, w tym ich dodawanie, usuwanie i modyfikowanie.
Oprogramowanie pośredniczące jest odpowiedzialne za zapewnienie, że wszelkie zmiany dokonane przez użytkownika w jego zadaniach, takie jak dodawanie, usuwanie lub edytowanie, skutkują wysłaniem poprawnych aktualizacji do reduktora sklepu, dzięki czemu może on zarządzać i utrzymywać dokładną reprezentację stanu aplikacji.
Renderowanie komponentu To-Do
Włączenie komponentu To-do do kontekstu komponentu strony poprzez jego zaimportowanie.
Aby wykonać żądane zadanie, należy uzyskać dostęp do pliku “page.js” znajdującego się w folderze “src/app” projektu. Po uzyskaniu dostępu do tego pliku uprzejmie usuń niepotrzebny wcześniej istniejący kod powiązany z Next.js i wstaw do niego dostarczony fragment kodu.
import styles from './page.module.css'
import Todo from '../components/Todo'
export default function Home() {
return (
<main className={styles.main}>
<Todo />
</main>
)
}
Rzeczywiście, dzięki implementacji React Context w aplikacji To-do Next.js można skutecznie obsługiwać i manipulować procesem zarządzania stanem w bardziej efektywny sposób.
Korzystanie z React Context API z innymi technologiami zarządzania stanem
Integracja React Context API z dodatkowymi rozwiązaniami do zarządzania stanem, takimi jak Redux, daje możliwość wykorzystania zalet obu systemów w tandemie. Stosując tę hybrydową strategię, programiści mogą wykorzystać mocne strony każdej z technologii i zoptymalizować wydajność aplikacji, wykorzystując najbardziej odpowiednie narzędzia dla określonych krytycznych komponentów w architekturze oprogramowania.
Dzięki takiemu podejściu można wykorzystać zalety oferowane przez różne metody zarządzania stanem w celu opracowania skutecznych i dobrze zorganizowanych systemów oprogramowania.