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

React中使用useState钩子实现深层嵌套对象值修改与字段增删

React深层嵌套状态更新实现方案

原生useState实现(无第三方依赖)

React状态更新的核心原则是必须返回全新的状态对象,不能直接修改原状态,否则不会触发组件重渲染。所有层级的更新都需要逐层拷贝被修改路径上的所有对象/数组。
假设你的状态定义如下:

const [state, setState] = useState(/* 你的初始嵌套对象 */)

以下是各场景的实现示例:

1. 更新/新增/删除key1.key2

// 直接替换整个key2数组
setState(prev => ({
  ...prev,
  key1: {
    ...prev.key1,
    key2: 新的key2数组
  }
}))

// 新增元素到key2末尾
setState(prev => ({
  ...prev,
  key1: {
    ...prev.key1,
    key2: [...prev.key1.key2, 新增的元素对象]
  }
}))

// 删除key2中指定索引的元素
const delIndex = 1 // 要删除的索引
setState(prev => ({
  ...prev,
  key1: {
    ...prev.key1,
    key2: prev.key1.key2.filter((_, idx) => idx !== delIndex)
  }
}))

2. 更新/新增/删除key1.key2[index].field1

const key2Index = 0 // key2数组的目标索引
const targetValue = '新的值'

// 更新field1
setState(prev => {
  const newKey2 = [...prev.key1.key2]
  newKey2[key2Index] = {
    ...newKey2[key2Index],
    field1: targetValue
    // 新增键直接在这里加,比如 newField: 'xxx'
  }
  // 删除键用解构排除,比如:
  // const { field1, ...restItem } = newKey2[key2Index]
  // newKey2[key2Index] = restItem
  return {
    ...prev,
    key1: {
      ...prev.key1,
      key2: newKey2
    }
  }
})

3. 更新/新增/删除key1.key2[index].field2[index]

const key2Index = 0
const field2Index = 1
const targetValue = '新的值'

setState(prev => {
  const newKey2 = [...prev.key1.key2]
  const key2Item = { ...newKey2[key2Index] }
  key2Item.field2 = [...key2Item.field2]
  // 更新指定位置的值
  key2Item.field2[field2Index] = targetValue
  // 新增元素用push逻辑:key2Item.field2.push('新增值')
  // 删除元素用filter:key2Item.field2 = key2Item.field2.filter((_, idx) => idx !== field2Index)
  newKey2[key2Index] = key2Item
  return {
    ...prev,
    key1: {
      ...prev.key1,
      key2: newKey2
    }
  }
})

4. 更新key1.key2[index].field3[index].ff2[index]

const key2Index = 0
const field3Index = 0
const ff2Index = 0
const targetValue = '新的值'

setState(prev => {
  const newKey2 = [...prev.key1.key2]
  const key2Item = { ...newKey2[key2Index] }
  key2Item.field3 = [...key2Item.field3]
  const field3Item = { ...key2Item.field3[field3Index] }
  field3Item.ff2 = [...field3Item.ff2]
  field3Item.ff2[ff2Index] = targetValue
  key2Item.field3[field3Index] = field3Item
  newKey2[key2Index] = key2Item
  return {
    ...prev,
    key1: {
      ...prev.key1,
      key2: newKey2
    }
  }
})

5. 更新最深层key1.key2[index].field3[index].ff3[index][index].key

const key2Index = 0
const field3Index = 0
const ff3FirstIndex = 0
const ff3SecondIndex = 1
const targetKey = 'f2'
const targetValue = 3

setState(prev => {
  const newKey2 = [...prev.key1.key2]
  const key2Item = { ...newKey2[key2Index] }
  key2Item.field3 = [...key2Item.field3]
  const field3Item = { ...key2Item.field3[field3Index] }
  field3Item.ff3 = [...field3Item.ff3]
  const ff3FirstArr = [...field3Item.ff3[ff3FirstIndex]]
  const ff3Item = { ...ff3FirstArr[ff3SecondIndex] }
  ff3Item[targetKey] = targetValue
  ff3FirstArr[ff3SecondIndex] = ff3Item
  field3Item.ff3[ff3FirstIndex] = ff3FirstArr
  key2Item.field3[field3Index] = field3Item
  newKey2[key2Index] = key2Item
  return {
    ...prev,
    key1: {
      ...prev.key1,
      key2: newKey2
    }
  }
})

简化方案:使用Immer

原生写法层级越深越容易漏拷贝导致状态不更新,推荐使用Immer库简化不可变更新逻辑,不需要手动逐层拷贝,直接修改 draft 对象即可,Immer会自动生成全新的不可变状态。

使用示例

  1. 安装Immer和use-immer后定义状态:
import { useImmer } from 'use-immer'
const [state, updateState] = useImmer(/* 初始状态 */)
  1. 任意层级的更新都可以直接操作:
// 更新最深层的值
updateState(draft => {
  draft.key1.key2[0].field3[0].ff3[0][1].f2 = 3
})

// 给field2新增元素
updateState(draft => {
  draft.key1.key2[0].field2.push('新增值')
})

// 删除指定键
updateState(draft => {
  delete draft.key1.key2[0].field1
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 05:54:07