You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Immer基于前一次状态更新React组件的state

React中结合Immer使用setState更新函数的实现方案

核心解决方案

将produce方法嵌套在setState的更新回调中,即可同时访问到React官方保证的最新前序状态,以及Immer提供的可变草稿代理:

handleClick(clickedOption) {
  this.setState(prevState => produce(prevState, draft => {
    // 用原始前序状态做索引查找,结果准确
    const index = prevState.fooBar.selectedOptions.indexOf(clickedOption);
    if (index > -1) {
      draft.fooBar.selectedOptions.splice(index, 1);
    } else {
      draft.fooBar.selectedOptions.push(clickedOption);
    }
  }));
}

方案说明

  • 外层setState传入的更新回调接收的prevState是React官方保证的最新前序状态,完全规避直接读取this.state可能出现的状态过期问题
  • prevState是未被代理的原始状态对象,执行indexOf、等值对比等操作返回的结果完全准确
  • 所有状态修改仍然操作draft代理,Immer会自动生成符合不可变规范的新状态返回给setState,无需手动处理嵌套对象的解构拷贝

替代方案:使用Immer内置original工具函数

如果偏好Immer的柯里化写法,可以直接调用Immer提供的original方法获取草稿对应的原始状态:
首先导入original:

import { produce, original } from 'immer';

修改后的状态更新代码:

handleClick(clickedOption) {
  this.setState(produce(draft => {
    // 获取草稿对应的原始状态数组
    const originalOptions = original(draft.fooBar.selectedOptions);
    const index = originalOptions.indexOf(clickedOption);
    if (index > -1) {
      draft.fooBar.selectedOptions.splice(index, 1);
    } else {
      draft.fooBar.selectedOptions.push(clickedOption);
    }
  }));
}

方案说明

original是Immer官方提供的工具方法,用于返回代理草稿对应的原始状态值,用它执行对比、查找类操作结果完全准确。

内容的提问来源于stack exchange,提问作者Fateh Khalsa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 03:36:03