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

React中如何将新增的单个设备对象推入目标数组devicesList?

问题:React中向数组添加单个设备对象避免嵌套数组

我正在使用React,需要将数组devices中的新增单个设备对象推入currentRoom内的空数组devicesList。devices的控制台输出示例如下:

(2) [Device, Device]
0: Device {deviceName: 'AC', deviceStatus: 'off'}
1: Device {deviceName: 'TV', deviceStatus: 'off'}

我有一个点击触发的函数,期望每次向devices添加新设备时,通过push()将该设备加入devicesList末尾。但使用devicesList.push(devices)会导致嵌套数组,当前输出为:

devicesList: Array(3)
0: [] 
1: [Device]
Device {deviceName: 'Light', deviceStatus: 'off'}
2: (2) [Device, Device]
0: Device {deviceName: 'Light', deviceStatus: 'off'}
1: Device {deviceName: 'Stereo', deviceStatus: 'off'}
length: 3

期望devicesList输出为:

devicesList: Array(3)
0: []
1: [Device]
Device {deviceName: 'Light', deviceStatus: 'off'}
2: [Device]
Device {deviceName: 'Stereo', deviceStatus: 'off'}
length: 3

相关代码如下:

const [showAdd, setShowAdd] = useState(false);

const [deviceName, setDeviceName] = useState('')

const [deviceStatus, setDeviceStatus] = useState('off')

const [devices, setDevices] = useState([])



const AddNewDevice = (deviceName, deviceStatus) => {
  
  //1st step: Validation of the device:

  let containsStereo = devices.some(e => e.deviceName === 'Stereo')
  let isBathroom = currentRoom.roomType === 'Bathroom'

  let devicesList = currentRoom.devicesList

  if ((containsStereo && deviceName == 'Stereo') || (!isBathroom && deviceName == 'Boiler') || (devicesList.length > 5)) return alert('error')
  else {
    
    //2nd if validated creation of new device

    const newDevice = new Device(deviceName, deviceStatus);
    console.log(newDevice); 

    setDevices([...devices, newDevice])
    console.log(devices);

    devicesList.push(devices);
  
    console.log(currentRoom);

  }

  return devicesList

}

解决方案

问题根源

  1. 嵌套数组原因:执行devicesList.push(devices)时,是把整个devices数组(包含所有历史设备)推入devicesList,而非刚创建的单个newDevice,导致多层嵌套。
  2. React状态违规:直接修改currentRoom.devicesList属于直接变更状态,React无法检测到该变化,不会触发组件重新渲染。

修正代码

假设currentRoom是通过useState声明的状态(const [currentRoom, setCurrentRoom] = useState(...)),修改后的AddNewDevice函数如下:

const AddNewDevice = (deviceName, deviceStatus) => {
  // 验证逻辑
  const containsStereo = devices.some(e => e.deviceName === 'Stereo');
  const isBathroom = currentRoom.roomType === 'Bathroom';
  const { devicesList } = currentRoom;

  if ((containsStereo && deviceName === 'Stereo') || (!isBathroom && deviceName === 'Boiler') || (devicesList.length > 5)) {
    alert('error');
    return;
  }

  // 创建新设备
  const newDevice = new Device(deviceName, deviceStatus);

  // 更新devices状态:生成新数组添加新设备
  const updatedDevices = [...devices, newDevice];
  setDevices(updatedDevices);

  // 更新currentRoom的devicesList:添加单个设备的数组(匹配期望格式)
  const updatedDevicesList = [...devicesList, [newDevice]];
  setCurrentRoom({
    ...currentRoom,
    devicesList: updatedDevicesList
  });

  console.log(updatedDevicesList);
  return updatedDevicesList;
};

关键说明

  • 使用扩展运算符(...)创建新数组,避免直接修改原状态数组,符合React状态不可变原则。
  • 向devicesList中推入[newDevice](单个设备的数组),而非整个devices数组,解决嵌套问题。
  • 通过setCurrentRoom更新房间状态,确保组件能感知到devicesList的变化并重新渲染。
  • 原代码中console.log(devices)会输出旧值(因为setDevices是异步操作),如需查看更新后的值,可直接打印updatedDevices变量,或通过useEffect监听devices状态变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:01:09