未捕获类型错误:无法将对象'#<Object>'的只读属性分配给



对于我目前正在处理的代码,我有一个非常复杂的数组,里面充满了对象。这个页面的重点是一次更改数组中一个对象的一个属性,因此,需要更新整个数组才能进行更改。数组初始化为…

const [allDevices, setAllDevices] = useState(initialDeviceNames)

其中,initialDeviceNames将是从查询中提取的填充对象,如果没有匹配的实例,则为空数组。看起来是这样的。。。

请注意,空对象(如果找不到具有匹配日期值的对象(将使每个数字属性都设置为{id: null, name: "No Driver Selected"}

0:
0: {id: 'dfebc7ce-ea4b-48d4-9fd9-7c2d02572e40', name: 'DANIEL STITT', type: 'Vehicle'}
1: {id: '64303dc1-0ba6-43bb-a25a-9885f9e8f2e3', name: 'KENNETH WILLIFORD', type: 'Vehicle'}
2: {id: '1a778957-b679-401b-972d-aeb32f84e667', name: 'JASON PITSNOGLE', type: 'Vehicle'}
3: {id: '1fcc9d60-fc6f-4e34-b5ab-c64d5ea8778a', name: 'VIRGINIA SHADE', type: 'Vehicle'}
4: {id: null, name: 'No Driver Assigned'}
5: {id: null, name: 'No Driver Assigned'}
6: {id: null, name: 'No Driver Assigned'}
amount: 6
name: "Vehicle"
remaining_drivers: (60) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
[[Prototype]]: Object
1:
0: {id: '1a778957-b679-401b-972d-aeb32f84e667', name: 'JASON PITSNOGLE', type: 'iPad'}
1: {id: 'dfebc7ce-ea4b-48d4-9fd9-7c2d02572e40', name: 'DANIEL STITT', type: 'iPad'}
2: {id: '1fcc9d60-fc6f-4e34-b5ab-c64d5ea8778a', name: 'VIRGINIA SHADE', type: 'iPad'}
3: {id: '203726da-dba7-4f74-9d86-919d6a02a282', name: 'DONNA HAGGERTY', type: 'iPad'}
4: {id: null, name: 'No Driver Assigned'}
5: {id: null, name: 'No Driver Assigned'}
6: {id: null, name: 'No Driver Assigned'}
7: {id: null, name: 'No Driver Assigned'}
8: {id: null, name: 'No Driver Assigned'}
9: {id: null, name: 'No Driver Assigned'}
10: {id: null, name: 'No Driver Assigned'}
amount: 10
name: "iPad"
remaining_drivers: (60) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
[[Prototype]]: Object

因此,一次更新一个显然很复杂。我必须在数组中找到正确的对象,然后在该对象内找到正确的数字属性,更改它,然后更新整个状态。我为此编写的代码一直有效,直到我添加了一些预填充功能。更新这些单个属性的代码如下所示。。。

const handleDriverSelection = (driver, index, superIndex, deviceObj) => {
// If driver is the same 
if (allDevices[superIndex][index].name == `${driver.firstname} ${driver.lastname}`){
}
// If active driver is empty
else if (allDevices[superIndex][index].name == "No Driver Assigned" || allDevices[superIndex][index] == 'undefined'){
console.log(allDevices)
let newArray = [...allDevices]
// The specific device drop selected will be set equal the the driver clicked
newArray[superIndex][index] = {
name: `${driver.firstname} ${driver.lastname}`, 
id: driver.id,
type: deviceObj.name
}
// This removes the driver from the list of remaining driver
newArray[superIndex].remaining_drivers = newArray[superIndex].remaining_drivers.filter( (remDriver) => {
if (driver != remDriver){
return remDriver
}
})

// This sets the state
setAllDevices(newArray)
}
// if active driver exists but is NOT the one inputted
else if (allDevices[superIndex][index].name != "No Driver Assigned" ){
console.log(allDevices)
let newArray = [...allDevices]
// This finds the driver that was previously selected and adds him/her back to the remaining list
// For each driver...
user.drivers.forEach( (dspDriver) => {
// if the driver iterated == the driver that was previously selected
if (allDevices[superIndex][index].name == `${dspDriver.firstname} ${dspDriver.lastname}`){
// Adds the driver to remaining drivers
newArray[superIndex].remaining_drivers = [...newArray[superIndex].remaining_drivers, dspDriver]
// Sets the current drop state to the driver selected
newArray[superIndex][index] = {
name: `${driver.firstname} ${driver.lastname}`, 
id: driver.id, 
type: deviceObj.name 
}
// Removes the driver selected from the list of remaining drivers
newArray[superIndex].remaining_drivers = newArray[superIndex].remaining_drivers.filter( (remDriver, index) => {
if (driver != remDriver){
return remDriver
}
})
setAllDevices(newArray)
}
})
}
}

这就是我非常困惑的地方——通过

let newArray = [...allDevices]

我认为newArray会创建一个与allDevices内容完全相同的数组。由于allDevices是本地状态,因此它是只读的。我理解这一点。我还知道,如果我写了let newArray = allDevicesnewArray也将是只读的,因为它不是一个新的数组,而是一个指向allDevices值的不同变量。因此,我不知道为什么这个ISNT工作,因为newArray根本不应该是只读的。我添加的代码有很多复杂的useEffects来处理查询、变异和刷新,所以我看不出它会对上面显示的代码产生什么影响,尤其是因为除了这段代码之外,newArray根本不存在。

如果我更进一步地创建一个新的相同数组,从原来的只读数组进一步扩展它,它就成功了。这意味着我改变了

let newArray = [...allDevices]

let newArray = []
allDevices.forEach( (device, index) => {
newArray[index] = {...device}
})

看起来有点多余,但我想问题是即使我创建了包含对象的数组的读写副本,我也没有明确创建每个对象的读写版本,作为初始数组的一部分,它一定也是只读的

相关内容

最新更新