深入理解 Redux:从手写核心到现代实践(附 RTK 衔接)
Redux 作为前端经典状态管理库,核心解决 “组件间状态共享” 与 “状态变更可追溯” 问题,适配大型 React 项目。这篇文章我通过结合「手写核心逻辑」与「现代工具 RTK」,拆解 Redux 原理,明晰 “底层原理” 与 “高效开发” 的协同路径
一、Redux 核心三要素:Action、Reducer、StoreRedux 遵循「单向数据流」,状态变更需经Action → Reducer → Store流程,确保可预测性。
1. Action:操作描述的 “消息载体”Action 是触发状态变更的 “入口”,本质是「平面对象」(需isPlainObject验证),核心作用是描述 “发生了什么操作”,可通过payload携带数据。
核心特性(结合手写代码)「必须含type属性」:标识操作类型(如INCREMENT),类型无强制约束(字符串、Symbol 均可),大型项目建议单独维护(如actionTypes.js)避免硬编码。
示例:
// 基础 Action 结构
constincrementAction = {
type:"INCREMENT",
payload:1
};
「Action 创建函数(Action Creator)」:用「纯函数」简化 Action 生成,函数无副作用(不修改参数、无异步、不影响外部环境)。
示例:
// 生成“增加计数”的 Action
constincrement =(step) =({
type:"INCREMENT",
payload: step
});
「bindActionCreators:自动分发 Action」
手动创建 Action 需调用store.dispatch(action)触发变更,bindActionCreators可增强 Action Creator,使其创建后「自动分发」,简化代码。
核心实现(手写逻辑):
functiongetAutodisPatchActionCreator(actionCreator, dispatch){
return(...args) ={
constaction = actionCreator(...args);
dispatch(action);
}
exportdefaultfunctionbindActionCreators(actionCreators, dispatch){
if(typeofactionCreators ==='function') {
returngetAutodisPatchActionCreator(actionCreators, dispatch);
}
constresult = {};
for(constkeyinactionCreators) {
constcreator = actionCreators[key];
if(typeofcreator ==='function') {
result[key] = getAutodisPatchActionCreator(creator, dispatch);
}
}
returnresult;
}
2. Reducer:状态计算的 “纯函数”Reducer 是 Redux 的 “状态计算核心”,接收当前state和 Action,返回「新状态」(不可修改原状态),决定 “如何根据操作变更状态”。
核心特性(结合手写代码)「必须是纯函数」:保障 Redux 可预测性,要求:
不修改入参state和action;无异步操作(如定时器、接口请求);不影响外部环境(如修改全局变量、操作 DOM)。
优势:纯函数便于测试、可还原状态,且能优化 React 组件渲染(避免不必要重绘)。「初始化状态的技巧」
创建 Store 时,Redux 自动分发「初始化 Action」(类型为@@redux/INIT + 随机字符串,由ActionTypes.INIT()生成),此时 Reducer 接收state = undefined,可通过「参数默认值」初始化状态:
// 计数状态管理示例
functioncountReducer(state =0, action){
switch(action.type) {
case"INCREMENT":
returnstate + action.payload;
case"DECREMENT":
returnstate - action.payload;
default:
returnstate;
}
}
「combineReducers:拆分复杂 Reducer」
大型项目状态结构复杂(如 “用户信息”“购物车”),需按 “状态模块” 拆分 Reducer,再用combineReducers合并为「根 Reducer」。
核心实现(手写逻辑):
exportdefaultfunctioncombineReducers(reducers){
validateReducers(reducers);
returnfunction(state = {}, action){
constnewState = {};
for(constkeyinreducers) {
if(reducers.hasOwnProperty(key)) {
constsubReducer = reducers[key];
newState[key] = subReducer(state[key], action);
}
}
returnnewState;
}
示例(合并 “用户” 与 “计数” 模块):
constrootReducer = combineReducers({
user: userReducer,
count: countReducer
});
// Store 状态结构:{ user: {...}, count: 0 }
3. Store:状态的 “统一容器”Store 是 Redux 中 “唯一的状态容器”,通过createStore(reducer)创建,封装「状态存储、分发 Action、监听状态变化」的核心能力。
核心方法(手写实现)「getState():获取当前状态」
直接返回 Store 内部保存的currentState,是组件获取状态的唯一途径:
functiongetState(){
returncurrentState;
}
「dispatch(action):触发状态变更」
唯一能修改状态的方法,流程:
① 验证 Action(必须是平面对象,且含type);
② 调用 Reducer,传入当前状态和 Action,计算新状态;
③ 执行所有监听器(listeners),通知状态变更。
核心代码:
functiondispatch(action){
if(!isPlainObject(action)) {
thrownewTypeError("action must be a plain object");
}
if(action.type ===undefined) {
thrownewTypeError("action must has a property of type");
}
currentState = currentReducer(currentState, action);
for(constlisteneroflisteners) {
listener();
}
}
「subscribe(listener):监听状态变化」
注册 “状态变更监听器”(无参函数),dispatch触发后执行所有监听器;返回 “取消监听” 函数,避免内存泄漏。
核心代码:
functionsubscribe(listener){
listeners.push(listener);
letisRemoved =false;
returnfunction(){
if(isRemoved)return;
constindex = listeners.indexOf(listener);
listeners.splice(index,1);
isRemoved =true;
}
「Store 初始化」
创建 Store 时,自动分发「初始化 Action」(ActionTypes.INIT()),触发 Reducer 执行,通过参数默认值完成状态初始化(无需手动传默认状态)。
二、Redux 工具函数与中间件1. 工具函数:保障核心逻辑合法性「isPlainObject(obj)」:验证平面对象(__proto__指向Object.prototype),避免非标准对象(如数组、类实例)导致逻辑异常。
exportdefaultfunctionisPlainObject(obj){
if(typeofobj !=="object")returnfalse;
returnObject.getPrototypeOf(obj) ===Object.prototype;
}
「ActionTypes」:生成随机初始化 Action 类型(如@@redux/INIT + 随机字符串),避免与业务 Action 冲突。
functiongetRandom(length){
returnMath.random().toString(36).slice(2, length +2).split("").join(".");
}
exportdefault{
INIT() {return`@@redux/INIT${getRandom(6)}`; },
UNKNOWN() {return`@@redux/PROBE_UNKNOWN_ACTION${getRandom(6)}`; }
};
2. 中间件:增强dispatch能力Redux 核心仅支持「同步 Action」,处理异步操作(如接口请求)需通过「中间件」扩展dispatch功能。
中间件本质是 “函数链”,在dispatch触发 Action 后、Reducer 执行前,插入自定义逻辑(如异步请求、日志、错误捕获)。常见中间件:
redux-thunk:支持「函数式 Action」(Action 可返回函数,内部执行异步操作);
redux-saga:用 Generator 管理复杂异步流程(如接口重试、竞态处理)。
「核心原理」:中间件包装store.dispatch,支持非标准 Action(如函数、Promise),待异步完成后,分发真正的 “同步 Action” 触发状态变更。
三、从手写 Redux 到 RTK:现代开发的演进现代开发中,Redux 官方推出「Redux Toolkit(RTK)」,封装createSlice(合并 Action 与 Reducer)、configureStore(简化 Store 创建,内置中间件)等工具,大幅减少重复代码(无需手动写combineReducers、bindActionCreators),已成为 Redux 开发的「推荐方案」。
手写核心 vs RTK:定位与价值「手写核心」:并非替代 RTK,而是为了「深入理解 Redux 底层逻辑」。掌握核心原理后,能更灵活应对 RTK 封装的 “黑盒场景”(如自定义中间件、调试复杂状态流)。「RTK」:基于 Redux 核心逻辑的「高效工具」,让开发更简洁(如createSlice自动生成 Action 与 Reducer),适合快速迭代的项目。RTK 关键工具示例「createSlice」:合并 Action 类型、Reducer、Action Creator,自动生成 Action(如increment)。
import{ createSlice }from'@reduxjs/toolkit';
constcounterSlice = createSlice({
name:'counter',
initialState:0,
reducers: {
increment:(state, action) =state + action.payload,
decrement:(state, action) =state - action.payload,
},
});
// 自动生成 Action Creator:counterSlice.actions.increment
「configureStore」:简化 Store 创建,内置redux-thunk、redux-devtools等中间件。
import{ configureStore }from'@reduxjs/toolkit';
conststore = configureStore({
reducer: rootReducer,
});
四、Redux 工作流程与核心价值1. 完整流程(手写与 RTK 通用)组件调用 Action Creator(或 RTK 的slice.actions)触发 Action;dispatch传递 Action 至 Reducer;Reducer 计算新状态,更新 Store;监听器(如 React 组件的重新渲染逻辑)触发组件更新,读取新状态(store.getState())。2. 核心价值Redux 通过「分离 Action、Reducer、Store」,让状态变更「可追溯、可测试」,尤其适配大型项目的复杂状态管理。
「手写核心」:是理解 Redux 设计思想的 “最佳路径”,掌握后能精准定位状态问题;「RTK」:是高效开发的 “助推器”,让 Redux 从 “繁琐配置” 转向 “简洁实践”。五、总结Redux 的核心价值在于「规范状态管理流程」,手写实现揭示其 “简洁而严谨” 的逻辑(纯函数、单向数据流);RTK 则是站在 Redux 肩膀上的 “现代工具”,让开发更高效。
对于我们开发者而言:
新手可先通过手写核心理解原理,再迁移到 RTK 简化开发;
进阶者需兼顾 “底层逻辑” 与 “工具应用”,让 Redux 真正服务于项目稳定性与可维护性。
二者相辅相成,共同构建前端状态管理的 “清晰脉络”。
AI编程资讯AI Coding专区指南:
https://aicoding.juejin.cn/aicoding
点击"阅读原文"了解详情~
阅读原文
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。 项目经理在线