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

React+Redux项目中如何用Immer.js更新嵌套对象的指定属性

错误原因

你之前的代码错误核心是:传入produce处理的是currentJob.job_texts数组,produce返回的是修改后的数组,你直接将数组作为参数传给了接收整个currentJob对象的updateCurrentJob方法,导致原currentJob对象被数组覆盖,所以无法正常运行。

正确实现

首先确保你已经正确安装并导入Immer:

import { produce } from 'immer';

在组件的事件回调中按如下方式编写即可:

function onTextChanged(event) {
  const newText = event.target.value;
  // 将完整的currentJob对象作为produce的第一个入参
  const updatedJob = produce(props.currentJob, draft => {
    // 查找匹配id的目标项,直接修改draft对应属性即可
    const targetJobText = draft.job_texts.find(item => item.id === props.jobText.id);
    if (targetJobText) {
      targetJobText.text = newText;
    }
  });
  props.updateCurrentJob(updatedJob);
}

优化建议

更推荐把状态修改逻辑放到Redux的reducer中处理,组件只需要传递更新所需的参数即可,代码更易维护:

  1. 组件内触发更新:
function onTextChanged(event) {
  props.updateJobText(props.jobText.id, event.target.value);
}

// mapDispatchToProps中新增对应方法
function mapDispatchToProps(dispatch) {
  return {
    updateJobText: (id, text) => dispatch({
      type: 'UPDATE_JOB_TEXT',
      payload: { id, text }
    })
  };
}
  1. Reducer中使用Immer处理不可变更新:
import { produce } from 'immer';

const initialState = {
  currentJob: {
    // 其他原有属性
    job_texts: []
  }
};

export default function jobReducer(state = initialState, action) {
  switch (action.type) {
    case 'UPDATE_JOB_TEXT':
      return produce(state, draft => {
        const { id, text } = action.payload;
        const target = draft.currentJob.job_texts.find(item => item.id === id);
        if (target) target.text = text;
      });
    default:
      return state;
  }
}

Immer会自动生成符合不可变要求的新状态,只会对修改到的节点做更新,不需要全量深拷贝,性能优于_.cloneDeep方案,也完全符合Redux的状态更新规范。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 21:09:02