5月27日 23:31

MobX 和 Redux 有什么区别?

MobX 和 Redux 有什么区别?面试中三句话说清楚:MobX 是响应式自动追踪,改了数据视图自动更新;Redux 是函数式单向数据流,必须 dispatch action 才能改状态。MobX 写得少但调试难预测,Redux 写得多但状态可追溯。选哪个看团队——要快用 MobX,要严用 Redux。

核心区别

维度MobXRedux
编程范式响应式 + 面向对象函数式 + 单向数据流
状态修改直接赋值,自动追踪dispatch action → reducer 返回新状态
样板代码极少较多(即使 RTK 也比 MobX 多)
状态结构嵌套对象随意写推荐扁平化 + normalize
时间旅行有限支持Redux DevTools 完整支持
学习曲线入门快,精通需理解响应式原理入门慢,但模式固定好掌握
TypeScript良好良好(RTK 出厂即支持)

代码对比:同一个 Todo

MobX 写法

javascript
import { makeAutoObservable, computed } from "mobx"; class TodoStore { todos = []; filter = "all"; constructor() { makeAutoObservable(this); } get filteredTodos() { if (this.filter === "completed") return this.todos.filter((t) => t.done); if (this.filter === "active") return this.todos.filter((t) => !t.done); return this.todos; } addTodo(text) { this.todos.push({ id: Date.now(), text, done: false }); } toggle(id) { const todo = this.todos.find((t) => t.id === id); if (todo) todo.done = !todo.done; } }

直接改属性,MobX 内部的依赖追踪机制会自动触发对应组件重渲染。这就是响应式的核心——你写的是普通赋值,背后 MobX 帮你做了订阅和通知。

Redux Toolkit 写法

2026 年 Redux 官方推荐用 Redux Toolkit(RTK),不再用 createStore 那套手写模板。

javascript
import { createSlice, configureStore, createSelector } from "@reduxjs/toolkit"; const todoSlice = createSlice({ name: "todos", initialState: { items: [], filter: "all" }, reducers: { addTodo: (state, action) => { state.items.push({ id: Date.now(), text: action.payload, done: false }); }, toggle: (state, action) => { const todo = state.items.find((t) => t.id === action.payload); if (todo) todo.done = !todo.done; }, setFilter: (state, action) => { state.filter = action.payload; }, }, }); export const { addTodo, toggle, setFilter } = todoSlice.actions; const store = configureStore({ reducer: { todos: todoSlice.reducer } }); // Selector(带 memo) const selectFiltered = createSelector( [(s) => s.todos.items, (s) => s.todos.filter], (items, filter) => { if (filter === "completed") return items.filter((t) => t.done); if (filter === "active") return items.filter((t) => !t.done); return items; } );

RTK 内置了 Immer,所以在 reducer 里可以直接修改state(实际产出的是不可变新对象)。这大大减少了 Redux 的样板代码量。

面试追问:MobX 的响应式原理是什么?

MobX 在属性读取时收集依赖(通过 Proxy 或 getter 劫持),在属性写入时通知所有观察者。组件渲染时读取 observable 属性,MobX 记录这个组件依赖这些属性;属性变化时,MobX 精确触发对应组件重渲染。所以 MobX 不需要手动 shouldComponentUpdateReact.memo,它天然做到了最小化更新。代价是调试时不容易追踪谁改了这个值,因为赋值点分散在代码各处。

面试追问:为什么 Redux 要求状态不可变?

两个原因。第一,不可变让引用比较成为可能——oldState !== newState 就知道状态变了,不用深比较,这是 Redux 性能模型的基础。第二,不可变保证了时间旅行调试——每次状态变更都产生新的快照,可以回退到任意历史节点。如果直接修改原对象,历史状态会被覆盖,DevTools 的时间旅行就废了。这也是 MobX 时间旅行支持有限的根本原因。

性能:谁更快?

2026 年基准测试数据:

操作MobXRedux Toolkit
简单更新0.3ms0.8ms
嵌套更新0.4ms1.2ms
内存占用3.1MB4.2MB

MobX 快在哪?它自动追踪依赖,只更新真正受影响的组件。Redux 每次 dispatch 后要过一遍 useSelector 的比较逻辑,组件需要自己决定要不要重渲染。当然,Redux 配合 reselect 做 memo 化后差距会缩小,但这是需要开发者手动做的。

怎么选?

选 MobX: 小团队快速迭代、状态嵌套深(比如树形编辑器)、团队 OOP 背景强、不想写样板代码。

选 Redux (RTK): 大型项目多人协作、需要严格的代码规范和可追溯的状态变更、需要 DevTools 时间旅行、团队函数式偏好。

都不选? 2026 年 Zustand(2.1KB)因为极简 API 和零样板代码,成为很多新项目的默认选择。它没有 MobX 的响应式黑盒,也没有 Redux 的模板负担。如果你的项目状态管理不复杂,Zustand 值得一看。

一句话总结

MobX 用魔法帮你省事,Redux 用规矩帮你兜底。面试答区别,先说范式(响应式 vs 函数式),再说可变性(可变 vs 不可变),最后说取舍(灵活 vs 可预测)。

标签:ReduxMobx