当前位置: 首页 > news >正文

【React】使用 useContext + useReducer 实现一个轻量的状态管理库

使用 useContext + useReducer 实现的轻量级状态管理,适合中小型 React 应用使用。


🧠 实现思路

  1. 使用 createContext 创建两个上下文:StateContextDispatchContext
  2. useReducer 管理状态逻辑。
  3. 创建一个 Provider 组件包裹应用。
  4. 提供两个 hooks:useGlobalState()useGlobalDispatch(),分别获取状态和派发方法。

✅ 示例代码

1️⃣ 创建状态管理库:store.js

import React, { createContext, useReducer, useContext } from 'react';// 定义初始状态
const initialState = {count: 0,user: null,
};// 定义 reducer
function reducer(state, action) {switch (action.type) {case 'INCREMENT':return { ...state, count: state.count + 1 };case 'DECREMENT':return { ...state, count: state.count - 1 };case 'SET_USER':return { ...state, user: action.payload };default:throw new Error(`Unknown action type: ${action.type}`);}
}// 创建两个上下文
const StateContext = createContext(null);
const DispatchContext = createContext(null);// 创建 Provider
export function GlobalProvider({ children }) {const [state, dispatch] = useReducer(reducer, initialState);return (<StateContext.Provider value={state}><DispatchContext.Provider value={dispatch}>{children}</DispatchContext.Provider></StateContext.Provider>);
}// 封装 hooks
export function useGlobalState() {const context = useContext(StateContext);if (context === undefined) {throw new Error('useGlobalState must be used within a GlobalProvider');}return context;
}export function useGlobalDispatch() {const context = useContext(DispatchContext);if (context === undefined) {throw new Error('useGlobalDispatch must be used within a GlobalProvider');}return context;
}

2️⃣ 使用示例

App.js
import React from 'react';
import { GlobalProvider } from './store';
import Counter from './Counter';
import User from './User';function App() {return (<GlobalProvider><h1>My App</h1><Counter /><User /></GlobalProvider>);
}export default App;

Counter.js
import React from 'react';
import { useGlobalState, useGlobalDispatch } from './store';function Counter() {const { count } = useGlobalState();const dispatch = useGlobalDispatch();return (<div><h2>Count: {count}</h2><button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button><button onClick={() => dispatch({ type: 'DECREMENT' })}>-</button></div>);
}export default Counter;

User.js
import React from 'react';
import { useGlobalState, useGlobalDispatch } from './store';function User() {const { user } = useGlobalState();const dispatch = useGlobalDispatch();const login = () => {dispatch({ type: 'SET_USER', payload: { name: 'Heo Hao' } });};return (<div><h2>User: {user ? user.name : 'Guest'}</h2><button onClick={login}>Login</button></div>);
}export default User;

🧩 优点

  • 不依赖第三方库(如 Redux、Zustand)
  • 轻量、易用、类型安全(可结合 TS)
  • 适合中小项目

相关文章:

  • 文件的秒传、分片上传以及断点续传 || Redis缓存减轻数据库读写压力
  • 比特币拼图解密工具
  • 外部记忆的组织艺术:集合、树、栈与队列的深度解析
  • [电赛]MSPM0G3507学习笔记(二) GPIO:led与按键(流水灯、呼吸灯,短按长按与双击,ui预览)
  • 你应该如何引入JavaScript
  • 再现重大BUG,微软紧急撤回Win 11六月更新
  • 力扣HOT100之技巧:31. 下一个排列
  • 学习笔记整理之状态图与状态图搜索
  • AI模型的泛化性的第一性原理是什么?
  • 解释器模式(Interpreter Pattern)
  • Spark on yarn的作业提交流程
  • AppInventor2原生进度条组件LinearProgress用法及注意点
  • 试过沃尔玛的无人机送货吗?今年覆盖范围将翻番
  • 傲火集团传媒基地武汉启幕 构建数字娱乐产业生态闭环
  • yolov5环境配置
  • 拉深工艺——有凸缘圆筒形件的拉深(实例分析)
  • slam--运动方程和观测方程
  • 【驱动设计的硬件基础】处理器的分类
  • 解决蓝牙MAC 地址倒序问题
  • 如何快速删除谷歌浏览器在mac启动台生成的网页图标
  • 百度做的网站字体侵权吗/一份完整的市场调查方案
  • gta 买房网站建设中/阿里网站seo
  • 有哪些网站可以做店面设计软件/营销策略案例
  • 今天的新闻内容50字/北京关键词优化服务
  • 制作网站注册登录模块的思维导图/在线智能识图
  • 青海公路建设市场信用信息服务网站/网络营销流程