【秋招备战】React状态管理方案:Redux vs MobX

Simon Lv2

朋友,听说你在准备秋招?那今天咱们来聊聊前端江湖里的两大门派——Redux 和 MobX。这两位可都是状态管理界的大佬,一个像少林寺的易筋经,招式规矩森严;一个像逍遥派的北冥神功,灵活自在。让我们一起揭开它们的神秘面纱。

第一章:初入江湖——为什么需要状态管理?

想象一下,你在开发一个电商网站。用户的购物车数据需要在导航栏、购物车页面、结账页面共享,如果没有状态管理,你就得像传话游戏一样,一层层把数据传下去:

// 没有状态管理的痛苦传话游戏
<App cartItems={cartItems}>
<Header cartItems={cartItems}>
<CartIcon cartItems={cartItems}>
<CartCount count={cartItems.length} /> // 终于到了!累死了...
</CartIcon>
</Header>
</App>

这就是传说中的”prop drilling”(属性钻孔),钻着钻着,你就想掀桌子了。

第二章:Redux——规矩森严的少林派

Redux 的基本招式

Redux 就像一个超级严格的图书管理员,它有三大金科玉律:

  1. 单一数据源(Single Source of Truth):整个应用只有一个 store,就像图书馆只有一个总目录
  2. State 是只读的:你不能直接改书,只能提交申请
  3. 使用纯函数修改:修改必须按规矩来,不能搞特殊

来看看 Redux 的基本套路:

// 1. 定义 Action(你的申请单)
const ADD_TO_CART = 'ADD_TO_CART';
const addToCart = (product) => ({
type: ADD_TO_CART,
payload: product
});

// 2. 创建 Reducer(图书管理员的处理规则)
const cartReducer = (state = [], action) => {
switch (action.type) {
case ADD_TO_CART:
// 注意!必须返回新对象,不能直接修改
return [...state, action.payload];
default:
return state;
}
};

// 3. 创建 Store(图书馆)
import { createStore } from 'redux';
const store = createStore(cartReducer);

// 4. 使用 Store
store.dispatch(addToCart({ id: 1, name: '秋招面试宝典', price: 99 }));
console.log(store.getState()); // [{ id: 1, name: '秋招面试宝典', price: 99 }]

Redux 的内功心法——实现原理

Redux 的核心其实就是一个发布-订阅模式,我来给你”解剖”一下它的内部构造:

// 简化版 Redux 实现(去掉了中间件等复杂功能)
function createStore(reducer, initialState) {
let state = initialState;
let listeners = []; // 订阅者名单

// 获取当前状态
const getState = () => state;

// 订阅变化
const subscribe = (listener) => {
listeners.push(listener);
// 返回取消订阅的函数(贴心不?)
return () => {
listeners = listeners.filter(l => l !== listener);
};
};

// 派发 action
const dispatch = (action) => {
// 通过 reducer 计算新状态
state = reducer(state, action);
// 通知所有订阅者:"兄弟们,数据更新了!"
listeners.forEach(listener => listener());
return action;
};

// 初始化 state
dispatch({ type: '@@INIT' });

return { getState, subscribe, dispatch };
}

看到了吗?Redux 就像一个严格的广播电台:

  1. dispatch 一个 action = 发送广播信号
  2. reducer 处理 = 电台处理信号
  3. 通知所有 listeners = 广播给所有收音机

Redux 在 React 中的实战

在 React 中使用 Redux,需要 react-redux 这个”翻译官”:

// 1. 使用 Provider 包裹应用
import { Provider } from 'react-redux';

function App() {
return (
<Provider store={store}>
<YourAppComponents />
</Provider>
);
}

// 2. 使用 hooks 连接组件
import { useSelector, useDispatch } from 'react-redux';

function ShoppingCart() {
// useSelector 就像一个监视器,盯着 state 的变化
const cartItems = useSelector(state => state.cart);
const dispatch = useDispatch();

const handleAddItem = (product) => {
dispatch(addToCart(product));
};

return (
<div>
<h2>购物车({cartItems.length}件商品)</h2>
{/* ... */}
</div>
);
}

第三章:MobX——自由奔放的逍遥派

如果说 Redux 是个严格的图书管理员,那 MobX 就是个贴心的私人助理。它会自动追踪你需要什么,然后在数据变化时自动更新。

MobX 的基本招式

import { makeObservable, observable, action, computed } from 'mobx';

class ShoppingCart {
items = [];

constructor() {
// 告诉 MobX:"帮我盯着这些东西"
makeObservable(this, {
items: observable,
addItem: action,
removeItem: action,
totalPrice: computed
});
}

// 直接修改,没有那么多规矩
addItem(product) {
this.items.push(product);
}

removeItem(id) {
const index = this.items.findIndex(item => item.id === id);
if (index > -1) {
this.items.splice(index, 1);
}
}

// 计算属性,自动缓存
get totalPrice() {
return this.items.reduce((sum, item) => sum + item.price, 0);
}
}

const cart = new ShoppingCart();

看到了吗?MobX 就像你的贴心小棉袄,你直接改数据就行,它会自动通知该通知的人。

MobX 的内功心法——响应式原理

MobX 的魔法主要来自于 ES6 的 Proxy(或者在老版本中用 Object.defineProperty)。让我来揭秘一下:

// 简化版 MobX 原理
function makeObservable(target) {
const observers = new Set(); // 观察者集合

// 使用 Proxy 拦截对象操作
return new Proxy(target, {
get(obj, prop) {
// 收集依赖:"哦,有人在读取这个属性"
if (currentObserver) {
observers.add(currentObserver);
}
return obj[prop];
},

set(obj, prop, value) {
obj[prop] = value;
// 通知观察者:"兄弟们,数据变了!"
observers.forEach(observer => observer());
return true;
}
});
}

// 追踪函数执行时访问了哪些属性
let currentObserver = null;

function autorun(fn) {
currentObserver = fn;
fn(); // 执行一次,收集依赖
currentObserver = null;
}

// 使用示例
const person = makeObservable({ name: '小明', age: 25 });

autorun(() => {
console.log(`${person.name} 今年 ${person.age} 岁`);
});

person.age = 26; // 自动触发 console.log

MobX 的精髓就是:

  1. 依赖收集:当你读取数据时,MobX 偷偷记下”谁在用这个数据”
  2. 自动更新:当数据变化时,MobX 通知所有用到这个数据的地方

这就像你在淘宝收藏了一个商品,降价时自动给你发通知一样贴心!

MobX 在 React 中的实战

import { observer } from 'mobx-react-lite';

// observer 是个高阶组件,让组件"有眼力见"
const ShoppingCart = observer(() => {
// 直接使用,没有 hook,没有 dispatch
const cart = useCart(); // 假设这是你的 cart store

return (
<div>
<h2>购物车({cart.items.length}件商品)</h2>
<p>总价:{cart.totalPrice}元</p>
<button onClick={() => cart.addItem(newProduct)}>
添加商品
</button>
</div>
);
});

第四章:江湖对决——Redux vs MobX

好了,两位大侠的绝学都展示完了,让我们来个正面对决:

学习曲线

Redux:就像学开手动挡汽车,一开始各种熄火,但学会了你就是老司机。

  • Action、Reducer、Store、Middleware… 概念一大堆
  • 必须理解函数式编程思想
  • 代码量多(这也叫 boilerplate)

MobX:像自动挡,上手就能开,但你可能不知道变速箱怎么工作的。

  • 面向对象,符合直觉
  • 装饰器语法很优雅
  • 代码量少

可预测性

Redux

// Redux 的每一步都有迹可循
dispatch(action) → reducer → new state → UI update
// 时间旅行调试,可以回放每个 action

MobX

// MobX 的更新是自动的,有时候像黑魔法
observable.value = newValue → ??? → UI update
// 调试时可能会想:"咦,这咋就更新了?"

性能优化

Redux

  • 需要手动优化(useSelector、reselect 等)
  • 容易产生不必要的渲染
  • 但优化后性能很好

MobX

  • 自动优化,只更新真正需要更新的组件
  • 细粒度的响应式更新
  • 开箱即用的好性能

使用场景

选 Redux 的场景

  • 大型应用,需要严格的数据流
  • 团队协作,需要统一的规范
  • 需要时间旅行调试
  • 需要持久化、同步等高级功能

选 MobX 的场景

  • 中小型应用,追求开发效率
  • 有很多派生状态(computed)
  • 团队熟悉面向对象编程
  • 不想写太多样板代码

第五章:实战技巧与注意事项

Redux 的坑与技巧

  1. 不可变更新的坑
// ❌ 错误:直接修改
state.items.push(newItem);

// ✅ 正确:返回新对象
return {
...state,
items: [...state.items, newItem]
};

// 💡 技巧:使用 Immer 简化不可变更新
import produce from 'immer';

const reducer = produce((draft, action) => {
// 现在可以直接修改 draft
draft.items.push(action.payload);
});
  1. 异步处理
// 使用 Redux Thunk 处理异步
const fetchUserData = (userId) => async (dispatch) => {
dispatch({ type: 'FETCH_START' });
try {
const data = await api.getUser(userId);
dispatch({ type: 'FETCH_SUCCESS', payload: data });
} catch (error) {
dispatch({ type: 'FETCH_ERROR', payload: error });
}
};

MobX 的坑与技巧

  1. 观察数组和对象
// ⚠️ 注意:MobX 4/5 需要使用 observable 数组的方法
class Store {
@observable items = [];

@action addItem(item) {
// ✅ 这样会触发更新
this.items.push(item);

// ❌ 这样不会触发更新(MobX 4/5)
// this.items[this.items.length] = item;
}
}
  1. 避免过度使用 computed
class Store {
@observable users = [];

// ✅ 好的 computed:有复杂计算
@computed get activeUsers() {
return this.users.filter(u => u.isActive && u.lastLogin > someDate);
}

// ❌ 不必要的 computed:太简单了
@computed get userCount() {
return this.users.length; // 直接用 users.length 就行
}
}

第六章:2024 年的新趋势

Redux Toolkit —— Redux 的现代化改造

Redux 听到了大家的抱怨,推出了 Redux Toolkit (RTK):

import { createSlice } from '@reduxjs/toolkit';

// 一个 slice 搞定 actions + reducer
const cartSlice = createSlice({
name: 'cart',
initialState: [],
reducers: {
addItem: (state, action) => {
// 可以直接修改!RTK 内置了 Immer
state.push(action.payload);
},
removeItem: (state, action) => {
return state.filter(item => item.id !== action.payload);
}
}
});

export const { addItem, removeItem } = cartSlice.actions;
export default cartSlice.reducer;

MobX 6 的新特性

MobX 6 带来了更简洁的 API:

import { makeAutoObservable } from 'mobx';

class Store {
items = [];

constructor() {
// 自动将所有属性和方法变成 observable/action
makeAutoObservable(this);
}

addItem(item) {
this.items.push(item);
}
}

第七章:面试高频问题

面试官:Redux 的中间件原理是什么?

你的回答:中间件就像快递的中转站,action 在到达 reducer 之前会经过中间件处理:

// 中间件的本质是函数组合
const middleware = store => next => action => {
console.log('dispatching', action);
const result = next(action); // 调用下一个中间件
console.log('next state', store.getState());
return result;
};

面试官:MobX 和 Vue 的响应式有什么区别?

你的回答

  • Vue 2:使用 Object.defineProperty,需要预定义属性
  • Vue 3 和 MobX:都使用 Proxy,可以动态添加属性
  • MobX 是显式声明(makeObservable),Vue 是自动的(data 函数)

结语:没有银弹,只有权衡

记住,Redux 和 MobX 都是工具,没有绝对的好坏。就像金庸小说里,降龙十八掌刚猛无比,凌波微步飘逸灵动,关键看你要打什么怪。

给秋招的你一些建议

  1. 两个都要了解,但精通一个就够了
  2. 理解原理比会用 API 更重要
  3. 项目中遇到状态管理的痛点,才能真正理解这些工具的价值
  4. 面试时能讲清楚权衡(trade-off)比死记硬背更加分

最后,祝你秋招顺利,offer 拿到手软!记住,技术只是工具,解决问题的思维才是核心竞争力。


P.S. 如果这篇文章对你有帮助,记得给未来的同事们也分享一下。毕竟,独乐乐不如众乐乐,一起进步才是真的进步!

  • 标题: 【秋招备战】React状态管理方案:Redux vs MobX
  • 作者: Simon
  • 创建于 : 2025-08-13 15:26:45
  • 更新于 : 2025-08-13 15:54:56
  • 链接: https://www.simonicle.cn/2025/08/13/【秋招备战】React路由管理方案:Redux vs MobX/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论