红宝书第四十五讲:状态管理核心工具详解:RxJS & Redux & MobX的奇妙世界

资料取自《JavaScript高级程序设计(第5版)》
查看总目录:红宝书学习大纲


一、状态管理:像仓库管理员管理物资

典型场景
当多个页面/组件需要共享数据时(例如用户登录信息、购物车数据),需要一个集中管理机制。


二、RxJS:用"水流管道"管理数据变化

1. 核心概念:Observable 数据流 12

  • 想象成一条水管,数据像水流一样不断流动(例如:用户点击事件流、网络请求响应流)
  • 操作符 = 水管的过滤/加工工具(如防抖、筛选、合并等)

2. 实战例子:实时搜索关键词

// 🚰 创建一个输入框数据流
const searchInput$ = fromEvent(searchInputEl, 'input')
  .pipe(
    map(e => e.target.value),  // 提取输入值
    debounceTime(300),         // ⏳防抖:停止输入300ms后继续
    filter(text => text.length >= 2) // 过滤短文本
  );

// 🚿 订阅数据流(打开水龙头)
searchInput$.subscribe(keyword => {
  console.log('搜索关键词:', keyword);
});

运行效果

输入"react" → 自动忽略中间快速输入 → 最终传递"react"到订阅者

3. 操作流程图

flowchart LR
    A[用户输入事件] --> B[Observable流]
    B -->|debounceTime操作符| C{有效输入}
    C -->|map/filter操作符| D[处理后的值]
    D --> E[执行搜索逻辑]

三、Redux:中央仓库统一存储

1. 三大核心
Store(仓库):存储所有状态(唯一数据源)
Action(动作单据):描述状态如何变化(例如:{type: 'ADD_ITEM'})
Reducer(处理员):根据 Action 计算新状态(纯函数)

2. 流程图解

flowchart TB
    A[UI组件] -->|dispatch| B[Action]
    B --> C[Reducer]
    C --> D{计算新状态}
    D --> E[更新Store]
    E --> F[通知所有订阅者]

3. 代码示例:计数器

// 🏪 初始化仓库
const store = Redux.createStore((state = 0, action) => {
  switch(action.type) {
    case 'INCREMENT': 
      return state + 1; // ➕新状态
    default: 
      return state;
  }
});

// 📜 发送动作
store.dispatch({ type: 'INCREMENT' });

// 👂 监听变化
store.subscribe(() => {
  console.log('当前值:', store.getState());
});

输出当前值: 1


四、MobX:响应式编程的魔法

1. 核心概念

  • Observable(可观察状态):使用 @observablemakeAutoObservable 创建可观察的状态。当状态发生变化时,依赖它的视图会自动更新。
  • Computed(计算属性):基于可观察状态的派生值,会自动根据依赖状态的变化而更新。
  • Action(动作):用于修改可观察状态的方法,确保状态的变更在受控环境中进行。

2. 实战例子:计时器

import { makeAutoObservable } from "mobx";
import { observer } from "mobx-react";

class Timer {
  secondsPassed = 0;

  constructor() {
    makeAutoObservable(this);
  }

  increase() {
    this.secondsPassed += 1;
  }

  reset() {
    this.secondsPassed = 0;
  }
}

const myTimer = new Timer();

const TimerView = observer(({ timer }) => (
  <button onClick={() => timer.reset()}>
    已过秒数:{timer.secondsPassed}
  </button>
));

setInterval(() => {
  myTimer.increase();
}, 1000);

在这个例子中,Timer 类的 secondsPassed 是一个可观察状态,increasereset 是动作。TimerView 组件通过 observer 包裹后,会自动响应 secondsPassed 的变化。

3. 流程图解

flowchart LR
    A[可观察状态] -->|变化| B[计算属性]
    A -->|变化| C[观察者]
    C --> D[自动更新视图]

五、三大工具对比

特性RxJS(水管工模式)Redux(中央仓库模式)MobX(响应式魔法)
数据流向多管道异步流动严格单向流动(Action → Store)基于依赖关系的自动响应式更新
适用场景复杂异步流(如聊天、实时搜索)全局状态同步(如用户权限、主题切换)简化状态管理,适合复杂应用
调试难度较高(需理解操作符链条)较低(有明确状态变更日志)较低(依赖关系清晰)
典型结合Angular 项目常用React 生态常见(常与 React-Redux 集成)React 生态(常与 mobx-react 集成)

六、开发小贴士

// RxJS + Redux 联合使用示例(处理异步 Action)
const fetchUserEpic = action$ => 
  action$.pipe(
    filter(action => action.type === 'FETCH_USER'),
    switchMap(action => 
      ajax.getJSON(`/api/users/${action.id}`).pipe(
        map(response => ({ type: 'USER_LOADED', user: response }))
      )
    )
  );

// 使用Redux中间件将RxJS与Redux连接

目录:总目录
上篇文章:红宝书第四十四讲:基于红宝书的两个动画库Anime.js和three.js介绍

下篇文章:红宝书第四十六讲:Node.js基础与API设计解析


  1. 《JavaScript高级程序设计(第5版)》RxJS 使用 Observable 模式处理异步数据流,提供丰富的操作符
  2. 《JavaScript高级程序设计(第5版)》RxJS 通过流式处理解决复杂的状态变化场景

kovli
13 声望6 粉丝