未捕获的类型错误:无法分配给对象“#”的只读属性

发布于 2025-01-19 18:12:44 字数 5544 浏览 0 评论 0原文

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

const [allDevices, setAllDevices] = useState(initialDeviceNames)

如果没有匹配的实例,则intialdeviceNames将是从查询中获取的填充对象,或者是空数组的填充对象。看起来像这样...

请注意,一个空对象(如果找到具有匹配日期值的没有)将使每个数字属性设置为{id:null,name:“未选择驱动程序”}

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,由于它是本地状态,因此仅阅读。我明白这一点。我也知道,如果我写了让newArray = alldevices newarray也只能读取,因为它不是新数组,而只是指向值的另一个变量alldevices 这样,我不知道为什么这是不起作用的,因为newarray根本不应该阅读。我添加的代码具有多种复杂的使用效应来处理查询,突变和刷新,因此我看不到它将如何影响我上面显示的代码,尤其是因为newarray在任何地方都不存在此代码。

For the code I am currently working on, I have a very complicated array filled with objects.
The point of this page is to change one property of one object in the array at a time, and as is such, the entire array needs to be updated to carry out that change.
The array is initialized as so...

const [allDevices, setAllDevices] = useState(initialDeviceNames)

where intialDeviceNames will either be a populated object fetched from a query, or an empty array if there is no matching instance. That will look like this...

note that an empty object (if none with a matching date value is found) will have every number property set to {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

So updating this one at a time is clearly complicated. I have to find the right object in the array, then find the right number property inside that object, change it, and then get the whole state to update. The code I had for this worked until I added some pre-population functionality. The code for updating any of these single properties will be shown below...

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)
                }
            })
        }
    }

This is where I'm getting very confused-- through the line

let newArray = [...allDevices]

I would think that newArray creates an array with the exact same contents of allDevices. allDevices, since it is a local state, is read-only. I understand this. I also understand that had I wrote let newArray = allDevices that newArray would also be read only since it would not be a new array but rather just a different variable pointing to the value of allDevices.
As is such, I have no idea why this ISNT working, since newArray shouldn't be read-only at all. The code I added had a multitude of complicated useEffects to handle querying, mutating and refreshing, so I can't see how it would effect the code I showed above, especially since newArray doesn't exist anywhere but this code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一场信仰旅途 2025-01-26 18:12:44

如果我在创建一个新的相同阵列方面走得更远,从原始的读取数组中进一步促进了它,则可以使用。这意味着我更改

let newArray = [...allDevices]

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

似乎有些多余,但是我想问题是即使我创建了包含对象的数组的读取和写作,但我并没有明确创建一个读取 -每个对象的版本,作为初始数组的一部分,也必须仅读取

If I went a step further in creating a new identical array, furthering it from the original read-only array, it worked. This means to say I changed

let newArray = [...allDevices]

to

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

Seems a little redundant, but I suppose the issue was that even though I created a read-and-write duplicate of the array which contained the objects, I didn't explicitly create a read-and-write version of each object, which, as a part of the initial array, must have also been read only

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文