createContext+useContext+useReducer組合管理React復雜狀態

createContextuseContextuseReducer 的組合是 React 中管理全局狀態的一種常見模式。這種模式非常適合在不引入第三方狀態管理庫(如 Redux)的情況下,管理復雜的全局狀態。

以下是一個經典的例子,展示如何使用 createContextuseContextuseReducer 來實現一個簡單的全局狀態管理。

示例:Todo 應用

我們將實現一個簡單的 Todo 應用,支持以下功能:

  1. 添加任務
  2. 刪除任務
  3. 切換任務完成狀態

1. 定義全局狀態和操作

TodoContext.tsx

import React, { createContext, useReducer, useContext, ReactNode } from 'react';// 定義 Todo 項的類型
interface Todo {id: number;text: string;completed: boolean;
}// 定義全局狀態的類型
interface TodoState {todos: Todo[];
}// 定義操作類型
type TodoAction =| { type: 'ADD_TODO'; payload: string }| { type: 'TOGGLE_TODO'; payload: number }| { type: 'DELETE_TODO'; payload: number };// 定義初始狀態
const initialState: TodoState = {todos: [],
};// 定義 reducer 函數
const todoReducer = (state: TodoState, action: TodoAction): TodoState => {switch (action.type) {case 'ADD_TODO':return {...state,todos: [...state.todos,{ id: Date.now(), text: action.payload, completed: false },],};case 'TOGGLE_TODO':return {...state,todos: state.todos.map((todo) =>todo.id === action.payload? { ...todo, completed: !todo.completed }: todo),};case 'DELETE_TODO':return {...state,todos: state.todos.filter((todo) => todo.id !== action.payload),};default:return state;}
};// 創建 Context
const TodoContext = createContext<{state: TodoState;dispatch: React.Dispatch<TodoAction>;
} | null>(null);// 創建 Provider 組件
export const TodoProvider = ({ children }: { children: ReactNode }) => {const [state, dispatch] = useReducer(todoReducer, initialState);return (<TodoContext.Provider value={{ state, dispatch }}>{children}</TodoContext.Provider>);
};// 自定義 Hook,用于使用 TodoContext
export const useTodoContext = () => {const context = useContext(TodoContext);if (!context) {throw new Error('useTodoContext must be used within a TodoProvider');}return context;
};

2. 使用全局狀態

App.tsx

import React, { useState } from 'react';
import { TodoProvider, useTodoContext } from './TodoContext';const TodoList = () => {const { state, dispatch } = useTodoContext();return (<div><h2>Todo List</h2><ul>{state.todos.map((todo) => (<li key={todo.id}><spanstyle={{textDecoration: todo.completed ? 'line-through' : 'none',cursor: 'pointer',}}onClick={() => dispatch({ type: 'TOGGLE_TODO', payload: todo.id })}>{todo.text}</span><button onClick={() => dispatch({ type: 'DELETE_TODO', payload: todo.id })}>Delete</button></li>))}</ul></div>);
};const AddTodo = () => {const { dispatch } = useTodoContext();const [text, setText] = useState('');const handleAddTodo = () => {if (text.trim()) {dispatch({ type: 'ADD_TODO', payload: text });setText('');}};return (<div><inputtype="text"value={text}onChange={(e) => setText(e.target.value)}placeholder="Add a new task"/><button onClick={handleAddTodo}>Add</button></div>);
};const App = () => {return (<TodoProvider><h1>Todo App</h1><AddTodo /><TodoList /></TodoProvider>);
};export default App;

3. 代碼解釋

  1. TodoContext:
    • 使用 createContext 創建一個全局狀態的上下文。
    • 使用 useReducer 管理全局狀態和操作。
  2. TodoProvider:
    • 包裹應用的根組件,提供全局狀態和 dispatch 方法。
  3. useTodoContext:
    • 自定義 Hook,用于簡化 useContext 的使用,并確保上下文只能在 TodoProvider 內部使用。
  4. todoReducer:
    • 定義了如何根據不同的操作(ADD_TODO、TOGGLE_TODO、DELETE_TODO)更新全局狀態。
  5. 組件分離:
    • AddTodo 組件負責添加任務。
    • TodoList 組件負責顯示任務列表,并支持切換任務狀態和刪除任務。

4. 優勢

  • 清晰的狀態管理
    • 使用 useReducer 將狀態更新邏輯集中在一個地方,便于維護和擴展。
  • 全局狀態共享
    • 使用 createContext 和 useContext 實現全局狀態共享,無需手動傳遞 props。
  • 組件解耦
    • 通過上下文和 dispatch,各組件可以獨立處理自己的邏輯,而無需直接依賴其他組件。

5. 總結

createContext + useContext + useReducer 是一種輕量級的全局狀態管理方案,適合中小型項目。它的核心思想是:

  1. 使用 createContext 提供全局狀態。
  2. 使用 useReducer 管理狀態更新邏輯。
  3. 使用 useContext 在組件中訪問和操作全局狀態。

這種模式簡單易用,且不需要引入額外的狀態管理庫,非常適合 React 項目中需要共享狀態的場景。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/74966.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/74966.shtml
英文地址,請注明出處:http://en.pswp.cn/web/74966.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

記一次常規的網絡安全滲透測試

目錄&#xff1a; 前言 互聯網突破 第一層內網 第二層內網 總結 前言 上個月根據領導安排&#xff0c;需要到本市一家電視臺進行網絡安全評估測試。通過對內外網進行滲透測試&#xff0c;網絡和安全設備的使用和部署情況&#xff0c;以及網絡安全規章流程出具安全評估報告。本…

el-table,新增、復制數據后,之前的勾選狀態丟失

需要考慮是否為 更新數據的方式不對 如果新增數據的方式是直接替換原數據數組&#xff0c;而不是通過正確的響應式數據更新方式&#xff08;如使用 Vue 的 this.$set 等方法 &#xff09;&#xff0c;也可能導致勾選狀態丟失。 因為 Vue 依賴數據的響應式變化來準確更新視圖和…

第15屆藍橋杯java-c組省賽真題

目錄 一.拼正方形 1.題目 2.思路 3.代碼 二.勁舞團 1.題目 2.思路 3.代碼 三.數組詩意 1.題目 2.思路 3.代碼 四.封閉圖形個數 1.題目 2.思路 3.代碼 五.吊墜 1.題目 六.商品庫存管理 1.題目 2.思路 3.代碼 七.挖礦 1.題目 2.思路 3.代碼 八.回文字…

玄機-應急響應-入侵排查

靶機排查目標&#xff1a; 1.web目錄存在木馬&#xff0c;請找到木馬的密碼提交 查看/var/www/html。 使用find命令查找 find ./ -type f -name "*.php | xargs grep "eval("查看到1.php里面存在無條件一句話木馬。 2.服務器疑似存在不死馬&#xff0c;請找…

usbip學習記錄

USB/IP: USB device sharing over IP make menuconfig配置&#xff1a; Device Drivers -> Staging drivers -> USB/IP support Device Drivers -> Staging drivers -> USB/IP support -> Host driver 如果還有作為客戶端的需要&#xff0c;繼續做以下配置&a…

愛普生高精度車規晶振助力激光雷達自動駕駛

在自動駕駛技術快速落地的今天&#xff0c;激光雷達作為車輛的“智慧之眼”&#xff0c;其測距精度與可靠性直接決定了自動駕駛系統的安全上限。而在這雙“眼睛”的核心&#xff0c;愛普生&#xff08;EPSON&#xff09;的高精度車規晶振以卓越性能成為激光雷達實現毫米級感知的…

28--當路由器開始“宮斗“:設備控制面安全配置全解

當路由器開始"宮斗"&#xff1a;設備控制面安全配置全解 引言&#xff1a;路由器的"大腦保衛戰" 如果把網絡世界比作一座繁忙的城市&#xff0c;那么路由器就是路口執勤的交通警察。而控制面&#xff08;Control Plane&#xff09;就是警察的大腦&#xf…

58.基于springboot老人心理健康管理系統

目錄 1.系統的受眾說明 2.相關技術 2.1 B/S結構 2.2 MySQL數據庫 3.系統分析 3.1可行性分析 3.1.1時間可行性 3.1.2 經濟可行性 3.1.3 操作可行性 3.1.4 技術可行性 3.1.5 法律可行性 3.2系統流程分析 3.3系統功能需求分析 3.4 系統非功能需求分析 4.系統設計 …

去中心化固定利率協議

核心機制與分類 協議類型&#xff1a; 借貸協議&#xff08;如Yield、Notional&#xff09;&#xff1a;通過零息債券模型&#xff08;如fyDai、fCash&#xff09;鎖定固定利率。 收益聚合器&#xff08;如Saffron、BarnBridge&#xff09;&#xff1a;通過風險分級或博弈論…

反射率均值與RCS均值的計算方法差異

1. 反射率均值&#xff08;Mean Reflectance&#xff09; 定義&#xff1a; 反射率是物體表面反射的電磁波能量與入射能量的“比例”&#xff0c;通常以百分比或小數表示。 反射率均值是對多個測量點反射率的算術平均&#xff0c;反映目標區域整體的平均反射特性。 特點&a…

[MySQL初階]MySQL(8)索引機制:下

標題&#xff1a;[MySQL初階]MySQL&#xff08;8&#xff09;索引機制&#xff1a;下 水墨不寫bug 文章目錄 四、從問題到底層&#xff0c;從現象到本質1.為什么插入的數據默認排好序2.MySQL的Page&#xff08;1&#xff09;為什么選擇用Page&#xff1f;&#xff08;2&#x…

Access:在移動互聯網與AI時代煥發新生

Microsoft Access&#xff1a;在移動互聯網與AI時代煥發新生 在移動互聯網和人工智能&#xff08;AI&#xff09;技術快速發展的今天&#xff0c;許多傳統工具被認為已經過時。然而&#xff0c;Microsoft Access&#xff0c;這款曾經風靡一時的數據庫&#xff0c;真的已經被淘…

【無人機】無人機PX4飛控系統高級軟件架構

目錄 1、概述&#xff08;圖解&#xff09; 一、數據存儲層&#xff08;Storage&#xff09; 二、外部通信層&#xff08;External Connectivity&#xff09; 三、核心通信樞紐&#xff08;Message Bus&#xff09; 四、硬件驅動層&#xff08;Drivers&#xff09; 五、飛…

【項目日記】高并發服務器項目總結

生活總是讓我們遍體鱗傷&#xff0c; 但到后來&#xff0c; 那些受傷的地方一定會變成我們最強壯的地方。 -- 《老人與海》-- 高并發服務器項目總結 模塊關系圖項目工具模塊緩沖區模塊通用類型模塊套接字socket模塊信道Channel模塊多路轉接Poller模塊 Reactor模塊時間輪Tim…

Vue項目 bug 解決

Vue2項目部署失敗 從gitee 上拉下一個前端項目&#xff0c;然后npm install&#xff0c;報錯如下&#xff1a; 解決辦法&#xff1a; 從 npm切換到cnpm&#xff1a;npm install -g cnpm執行命令export NODE_OPTIONS--openssl-legacy-provider下載依賴&#xff1a;cnpm instal…

接口自動化入門(四)

1. JMeter 的多組數據測試 1.1 使用 CSV 數據文件 JMeter 支持通過 CSV 文件提供多組測試數據&#xff0c;適用于參數化測試場景。具體步驟如下&#xff1a; 創建一個 CSV 文件&#xff0c;將測試數據以逗號分隔的形式存儲。例如&#xff1a; username,passworduser1,pass1u…

企業數據分析何時該放棄Excel?

在企業數據分析中,Excel 的適用數據量范圍取決于 數據復雜度、計算需求 和 硬件性能: 一、Excel 適合處理的數據量范圍 數據規模適用場景限制與風險≤10萬行- 日常報表 - 簡單數據透視表 - 基礎公式計算(如SUMIFS、VLOOKUP)處理流暢,無明顯性能問題10萬~50萬行- 較復雜分析…

群暉NAS的最好的下載方式(虛擬機安裝win系統安裝下載軟件)

一、背景 買NAS的其中一個用途就是下載&#xff0c;尤其是那種BT、磁力下載這種需要耗時較久的&#xff0c;開著電腦就是為了下載這種非常耗電和耗硬盤。 二、應對策略 既然有上面 “背景” 提到的痛點&#xff0c;有什么解決方式&#xff1f; NAS 上用docker安裝迅雷&…

Spring AI與阿里云開發實踐——生成式Java AI應用架構全解析

本文深度解析基于Spring框架與阿里云服務構建生成式AI應用的技術路徑&#xff0c;涵蓋架構設計、模型集成、性能優化三大維度。通過某金融企業智能客服系統實戰案例&#xff0c;揭示Java生態下AI應用開發的7個關鍵實踐要點&#xff0c;結合Gartner最新技術成熟度曲線&#xff0…

基于springboot體育俱樂部預約管理系統(源碼+lw+部署文檔+講解),源碼可白嫖!

摘要 隨著我國經濟的高速發展與人們生活水平的日益提高&#xff0c;人們對生活質量的追求也多種多樣。尤其在人們生活節奏不斷加快的當下&#xff0c;人們更趨向于足不出戶解決生活上的問題&#xff0c;線上管理系統展現了其蓬勃生命力和廣闊的前景。與此同時&#xff0c;在科…