如何在 Next.js 中使用 React Context 進行狀態管理 13
Next.js 提供了多種狀態管理方法。雖然其中一些方法需要安裝新庫,但 React 的 Context API 是內置的,因此它是減少外部依賴性的好方法。
React Context 允許在整個組件層次結構中輕鬆傳輸信息,從而無需進行侵入性的 prop 鑽探。事實證明,這對於維護全局相關數據(例如當前經過身份驗證的用戶的登錄狀態及其喜歡的主題)特別有利。
理解 React Context API
為了有效地深入研究代碼的實現,全面了解 React Context API 及其解決特定挑戰的目的至關重要。
利用 props 可以在互連元素之間實現信息的無縫傳輸,從而有助於通過分層結構將數據從上級組件傳輸到其下級組件。
該方法被證明是有利的,因為它明確地展示了依賴於特定信息的特定組件,以及這些數據在整個組件的層次結構中的後續進展。
然而,當具有復雜嵌套的組件需要共享相同的 props 時,可能會出現困難。這種情況可能會導致複雜化,並可能最終導致代碼變得更加複雜,維護起來更具挑戰性。這些問題以及其他問題都涉及與支柱鑽井相關的缺點。
React Context 通過提供一種統一的方法來創建和利用應用程序中各個組件必須可用的信息,從而解決了訪問全局數據的問題。
利用結構化數據容器有利於各種系統組件無縫檢索和操作信息。從而提高組織效率,確保複雜網絡內的最佳功能。
該項目的源代碼託管在我們的 GitHub 存儲庫上,感興趣的各方可以訪問。
Next.js 中的狀態管理入門 13 使用 React Context API
Next.js 服務器組件使開發人員能夠構建將客戶端平台的響應能力與服務器渲染內容相關的效率增益無縫集成的應用程序,從而在優化性能的同時提供卓越的用戶體驗。
Next.js 版本 13 默認情況下將服務器組件合併到應用程序的目錄中,現在被認為是穩定的。但需要注意的是,由於所有組件都是在服務器端渲染的,因此在嘗試集成客戶端庫或 API(例如 React Context)時可能會出現問題。
防止此問題的一種有效解決方案是利用“客戶端”標誌,該標誌可應用於 JavaScript 文件以執行客戶端代碼。
要啟動該過程,您可以在終端中使用以下步驟在本地計算機上建立 Next.js 13 開發環境:
npx create-next-app@latest next-context-api
要以復雜的方式訪問新創建的項目的目錄,請按照下列步驟操作: 1.使用適當的方法建立項目後,繼續通過目錄和文件的層次結構導航來定位其在文件系統上的物理位置,直到到達包含與項目相關的所有組件的指定文件夾。此過程可能涉及使用命令行界面或圖形用戶界面,具體取決於您的操作系統和偏好。
cd next-context-api
然後啟動開發服務器:
npm run dev
建立基本的 Next.js 項目結構後,我們可以構建一個基本的任務管理器應用程序,利用 React Context API 作為其狀態治理的主要手段。
創建上下文提供者
上下文提供者功能充當主要來源,各個組件從中獲取必要的全局信息,使它們能夠有效地與其環境進行交互。
請在項目目錄中創建一個名為src/context/Todo.context.js
的新文件,並將以下代碼粘貼到其中: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>
);
};
當前的配置為 React 建立了一個上下文框架,稱為“TodoContext”,它以空任務列表作為應用程序的初始狀態開始。
除了建立起始狀態之外,此上下文配置還包含一個減速器函數,該函數概述了幾種操作類型。這些操作類型的實現將導致上下文狀態根據執行的操作發生變化。例如,這些動作可能涉及上下文中待辦事項的插入、刪除或修改。
value
屬性表示上下文的起始狀態,reducer
屬性指定歸約操作函數。
當給定元素攝取 TodoContext 時,可以檢索所述上下文的當前條件,以及傳播用於修改其配置的信號的能力。
將上下文提供程序添加到 Next.js 應用程序
為了使上下文提供程序在 Next.js 應用程序的頂層呈現,並確保所有客戶端組件都可以訪問它,有必要將上下文包含在應用程序的根佈局組件中。
為了完成此任務,請訪問“src/app/layout.js”文件並利用上下文提供程序將子節點包含在 HTML 模板中,如下所示:
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>
);
}
創建一個待辦事項組件
為了在指定的目錄結構中創建新文件,請按照下列步驟操作:1.打開您喜歡的文本編輯器或集成開發環境 (IDE)。2.導航到項目的“src”文件夾。3.在“src”文件夾中,找到並選擇“components”子文件夾。4.單擊文本編輯器或 IDE 中的“新建文件”按鈕以生成新的空白文檔。5。將新創建的文件保存為“Todo.js”。這應該在“components”子文件夾和整個“src”文件夾中完成。6。保存文件後,您可以繼續將提供的代碼片段複製並粘貼到新的“Todo.js”文件中。確保縮進
合併必要的導入語句,包括 use client
標誌,並通過利用下面代碼片段中的適當標誌將此組件指定為客戶端組件:javascriptimport { use client } from’next/client’;const MyComponent=()=> {const [data, setData]=useState([]);//在這裡使用客戶端標誌…return ( {/* 你的組件的JSX 放在這裡*/} );};export default MyComponent;
"use client"
import { TodoContext } from "@/context/Todo.context";
import React, { useContext, useState } from "react";
接下來,我們將通過指定要使用 JavaScript 可擴展標記語言 (JSX) 在 Web 瀏覽器中呈現的 HTML 組件來描述應用程序的功能方面。
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>
);
}
該功能組件包含用於在列表中添加、修改和刪除任務的交互元素。這些組件是使用 React 的條件渲染功能構建的,這些功能根據索引變量的當前值顯示編輯和刪除按鈕。
最後,必須指定必要的狀態變量,並為功能組件主體中的每種操作類型實現適當的處理程序函數。為此,請合併以下代碼行。
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("");
};
上述功能職責包括在上下文狀態下管理用戶的任務,包括添加、刪除和修改。
中間件負責確保用戶對其待辦事項所做的任何更改(例如添加、刪除或編輯它們)都會將正確的更新發送到商店的減速器,以便它可以管理和維護準確的表示應用程序的狀態。
渲染待辦事項組件
通過導入將待辦事項組件合併到頁面組件的上下文中。
為了執行所需的任務,請訪問項目“src/app”文件夾中的“page.js”文件。訪問此文件後,請刪除與 Next.js 關聯的任何不必要的預先存在的代碼,並在其中插入提供的代碼片段。
import styles from './page.module.css'
import Todo from '../components/Todo'
export default function Home() {
return (
<main className={styles.main}>
<Todo/>
</main>
)
}
事實上,通過在 To-do Next.js 應用程序中實現 React Context,我們可以以更高效的方式有效地處理和操作狀態管理流程。
將 React Context API 與其他狀態管理技術結合使用
React Context API 與 Redux 等其他狀態管理解決方案的集成提供了同時利用兩個系統優勢的機會。通過採用這種混合策略,開發人員可以利用每種技術的優勢,並通過針對軟件架構中的特定關鍵組件使用最合適的工具來優化其應用程序的性能。
通過這種方法,人們可以利用各種狀態管理方法提供的優勢來開發有效且組織良好的軟件系統。