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

如何在React中修改数组内嵌套对象的属性值?

解决React中嵌套对象数组的状态更新问题

我明白你现在遇到的问题了——之前的代码直接修改了原对象的属性,而且对象展开的写法也有问题,导致状态更新没达到预期。咱们一步步来修正:

问题出在哪?

你之前的代码里有两个关键错误:

  • 直接修改了原对象的item.user.isDeleted = true,这违反了React状态不可变更新的原则,React依赖状态的引用变化来触发重渲染,直接修改原对象不会让组件重新渲染。
  • 对象展开的语法错误:{ ...item, item: (item.user.isDeleted = true) }这里的item:是多余的,你应该更新的是user属性,而不是新增一个item键。

正确的实现方式

我们需要在map遍历中,对匹配到的项进行深度不可变更新:先展开原item对象,再展开它的user对象,然后修改isDeleted为true,其他属性保持不变。

setStaff(prevStaff => {
  // 用prevState而不是直接用data,避免闭包问题
  return prevStaff.map(item => {
    if (item.id === id) {
      // 正确嵌套更新,返回新对象
      return {
        ...item,
        user: {
          ...item.user, // 展开原user的所有属性
          isDeleted: true // 修改目标属性
        }
      };
    }
    return item; // 不匹配的项直接返回
  });
});

为什么要这么写?

  • 使用prevStaff作为参数:这是React状态更新的最佳实践,当你的新状态依赖于之前的状态时,一定要用函数式更新,避免闭包导致的旧状态问题。
  • 不可变更新:通过展开运算符...创建新的对象和数组,而不是修改原对象,这样React能检测到状态变化,触发组件重渲染。

完整组件示例

如果是在函数组件里使用,完整的删除逻辑大概是这样:

import { useState } from 'react';

function StaffList() {
  const [staff, setStaff] = useState([
    {
      id: 2,
      adminId: 2,
      roleId: 1,
      storeId: 1,
      createdAt: "2021-08-26T16:57:49.000Z",
      updatedAt: "2021-08-26T16:57:49.000Z",
      user: {
        id: 2,
        empId: 0,
        firstName: "Test1",
        lastName: "Test2",
        email: "test@test3.com",
        phone: "0900-786013",
        password: "$2b$10$XPxzZuzKLSl3Rm9YVk7AheZfLbvTNVV0jmo.NR/b0IJuFejW/hCFa",
        isActive: true,
        isDeleted: false,
        createdAt: "2021-08-26T16:57:49.000Z",
        updatedAt: "2021-08-30T07:34:38.000Z",
      },
    },
  ]);

  const handleDelete = (id) => {
    setStaff(prevStaff => {
      return prevStaff.map(item => {
        if (item.id === id) {
          return {
            ...item,
            user: {
              ...item.user,
              isDeleted: true
            }
          };
        }
        return item;
      });
    });
  };

  return (
    <div>
      {staff.map(member => (
        <div key={member.id}>
          <p>{member.user.firstName} {member.user.lastName}</p>
          <button onClick={() => handleDelete(member.id)}>标记为删除</button>
        </div>
      ))}
    </div>
  );
}

export default StaffList;

这样点击按钮后,对应员工的user.isDeleted就会被正确设置为true,同时组件也会重新渲染展示更新后的状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 08:37:33