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

如何通过字符串路径更新Immer draft的嵌套属性?

问题

你需要在immer的produce流程中,通过传入的字符串格式属性路径,修改深度嵌套的对象/数组属性值,示例场景如下:

const data = { colors: [{id: 1, name: 'red'}] }

const path = "colors.0.name"
const nextValue = "dark red"


produce(data, (draft) => {
  // 在此处通过通用路径逻辑,将对应属性修改为dark red
})
实现方法

完全可以在draft回调内完成这个需求,不需要依赖额外工具库,核心是在回调内部沿着路径逐层遍历draft节点,最终完成赋值即可,immer会自动追踪所有层级的修改。

直接写一个通用的路径赋值工具函数,在produce回调里调用就行:

import { produce } from 'immer'

/**
 * 按字符串路径给immer draft设置属性值
 * @param {object|array} draft immer生成的代理对象
 * @param {string} path 点分隔的属性路径,数组下标直接传数字字符串即可
 * @param {any} value 要设置的目标值
 */
const setNestedValue = (draft, path, value) => {
  const keys = path.split('.')
  let node = draft
  // 遍历到目标属性的父节点
  for (let i = 0; i < keys.length - 1; i++) {
    node = node[keys[i]]
  }
  // 给目标属性赋值
  node[keys.at(-1)] = value
}

// 实际使用
const nextState = produce(data, (draft) => {
  setNestedValue(draft, path, nextValue)
})

注意事项

  • 上述实现默认传入的路径合法,即路径上的所有中间节点都真实存在。如果业务中存在路径断层的场景,可以在遍历过程中增加判断,按需自动创建缺失的对象/数组结构即可
  • 不需要手动把路径里的数字字符串转成Number类型,JS中通过字符串下标访问数组元素和数字下标效果完全一致
  • 路径遍历逻辑必须写在produce的回调内部执行,不要在回调外提前拿到路径对应节点的引用再修改,否则immer无法正确代理修改,会破坏不可变数据的生成逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:57:19