news 2026/6/10 17:36:30

03-状态管理与路由——01-Context + useReducer 模式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
03-状态管理与路由——01-Context + useReducer 模式

Context + useReducer 模式

一、为什么需要状态管理?

1.1 Props Drilling 问题

// ❌ 层层传递,繁琐且难以维护 <GrandParent user={user}> <Parent user={user}> <Child user={user}> <GrandChild user={user} /> </Child> </Parent> </GrandParent>

1.2 解决方案对比

方案适用场景优点缺点
Props简单父子组件简单直接层级深时繁琐
Context跨层级传递避免 props drilling过度使用影响性能
Context + useReducer中等复杂度应用轻量、内置比 Zustand 代码多
Zustand/Redux大型应用功能强大学习成本

二、Context + useReducer 基础

2.1 创建状态管理

// store/AppContext.js import React, { createContext, useContext, useReducer } from 'react'; // 1. 定义初始状态 const initialState = { user: null, theme: 'light', count: 0, notifications: [] }; // 2. 定义 Action 类型 const ACTIONS = { SET_USER: 'SET_USER', TOGGLE_THEME: 'TOGGLE_THEME', INCREMENT: 'INCREMENT', DECREMENT: 'DECREMENT', ADD_NOTIFICATION: 'ADD_NOTIFICATION', REMOVE_NOTIFICATION: 'REMOVE_NOTIFICATION' }; // 3. 定义 Reducer function appReducer(state, action) { switch (action.type) { case ACTIONS.SET_USER: return { ...state, user: action.payload }; case ACTIONS.TOGGLE_THEME: return { ...state, theme: state.theme === 'light' ? 'dark' : 'light' }; case ACTIONS.INCREMENT: return { ...state, count: state.count + 1 }; case ACTIONS.DECREMENT: return { ...state, count: state.count - 1 }; case ACTIONS.ADD_NOTIFICATION: return { ...state, notifications: [...state.notifications, action.payload] }; case ACTIONS.REMOVE_NOTIFICATION: return { ...state, notifications: state.notifications.filter(n => n.id !== action.payload) }; default: return state; } } // 4. 创建 Context const AppContext = createContext(); // 5. Provider 组件 export function AppProvider({ children }) { const [state, dispatch] = useReducer(appReducer, initialState); return <AppContext.Provider value={{ state, dispatch }}>{children}</AppContext.Provider>; } // 6. 自定义 Hook export function useAppContext() { const context = useContext(AppContext); if (!context) throw new Error('useAppContext must be used within AppProvider'); return context; }

2.2 使用状态管理

function Counter() { const { state, dispatch } = useAppContext(); return ( <div> <p>计数: {state.count}</p> <button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button> <button onClick={() => dispatch({ type: 'DECREMENT' })}>-</button> </div> ); } function ThemeToggle() { const { state, dispatch } = useAppContext(); return ( <button onClick={() => dispatch({ type: 'TOGGLE_THEME' })}> 当前主题: {state.theme} </button> ); }

三、实战:Todo 应用

3.1 Store 定义

const initialState = { todos: [], filter: 'all', loading: false, error: null }; const ACTIONS = { ADD_TODO: 'ADD_TODO', TOGGLE_TODO: 'TOGGLE_TODO', DELETE_TODO: 'DELETE_TODO', SET_FILTER: 'SET_FILTER', SET_LOADING: 'SET_LOADING' }; function todoReducer(state, action) { switch (action.type) { case ACTIONS.ADD_TODO: return { ...state, todos: [...state.todos, action.payload] }; case ACTIONS.TOGGLE_TODO: return { ...state, todos: state.todos.map(todo => todo.id === action.payload ? { ...todo, completed: !todo.completed } : todo ) }; case ACTIONS.DELETE_TODO: return { ...state, todos: state.todos.filter(todo => todo.id !== action.payload) }; case ACTIONS.SET_FILTER: return { ...state, filter: action.payload }; default: return state; } }

四、性能优化

4.1 拆分 Context

// 按职责拆分,避免不必要的重渲染 const UserContext = createContext(); const ThemeContext = createContext(); const NotificationContext = createContext();

4.2 使用 useMemo 优化值

function AppProvider({ children }) { const [state, dispatch] = useReducer(reducer, initialState); const value = useMemo(() => ({ state, dispatch }), [state]); return <AppContext.Provider value={value}>{children}</AppContext.Provider>; }

五、小结

要点说明
适用场景中小型应用、跨层级状态
核心组合Context + useReducer
性能优化拆分 Context、useMemo

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 17:31:10

基于 Harmony 6.0 应用的笔记与思维导图应用首页实现

基于 Harmony 6.0 应用的笔记与思维导图应用首页实现 前言 笔记是数字时代最被高估又最被低估的工具——一方面市面上有无数笔记应用&#xff0c;另一方面绝大多数用户的笔记最终都没有被回看。一款好的笔记应用要解决三个层面的问题——快速记录&#xff08;不打断思路&#x…

作者头像 李华
网站建设 2026/6/10 17:28:19

TensorFlow结构化数据输入管道:tf.data高性能实践指南

1. 项目概述&#xff1a;为什么结构化数据的输入管道不能“随便写个for循环”就完事&#xff1f;在TensorFlow生态里&#xff0c;tf.data这个模块常被初学者误认为是“给图像和文本准备的”&#xff0c;一碰到CSV、Parquet、数据库导出的表格数据&#xff0c;第一反应就是panda…

作者头像 李华
网站建设 2026/6/10 17:20:14

手把手教你用TI C2000 Ware库函数重构F28377x CAN通信代码(附中断配置)

基于C2000 Ware库函数的F28377x CAN通信开发实战指南 在嵌入式系统开发中&#xff0c;CAN总线因其高可靠性和实时性被广泛应用于工业控制、汽车电子等领域。对于使用TI TMS320F28377x系列DSP的开发者而言&#xff0c;直接操作寄存器实现CAN通信虽然能获得最大控制权&#xff0c…

作者头像 李华
网站建设 2026/6/10 17:20:12

数据科学新手避坑指南:从Excel到AI的72小时实战路径

1. 这不是工具清单&#xff0c;而是一份“数据科学新手避坑指南” 刚入行那会儿&#xff0c;我花整整两周时间装环境——Anaconda、TensorFlow、CUDA、cuDNN&#xff0c;版本对不上就报错&#xff0c;报错信息全是英文堆砌&#xff0c;连“ImportError: DLL load failed”都查…

作者头像 李华
网站建设 2026/6/10 17:17:34

告别DEM构建烦恼:用CloudCompare的‘泊松+栅格’组合拳,搞定复杂地形点云高程归一化

复杂地形点云高程归一化的高阶实践&#xff1a;CloudCompare泊松重建与栅格融合技术解析当面对山地、丘陵等复杂地形的点云数据时&#xff0c;传统的高程归一化方法往往捉襟见肘。单一的技术路线要么在边缘拟合上表现不佳&#xff0c;要么在细节保留上力不从心。本文将深入探讨…

作者头像 李华
网站建设 2026/6/10 17:15:55

从登录到无感刷新:一个真实Vue+SpringBoot项目的Token管理实战复盘

现代Web应用的双Token认证体系深度实践登录认证是每个Web应用的基础设施&#xff0c;但如何平衡安全性与用户体验一直是开发者面临的难题。去年我们团队负责的一个企业级SaaS项目&#xff0c;最初采用了简单的单Token方案&#xff0c;但随着业务复杂度提升&#xff0c;频繁的登…

作者头像 李华