Search code examples
javascriptreactjsreact-reduxsetstate

SetState and push object in array in nested dynamic array of objects in React JS


I have two array with same objects properties and I wanted to update only specific object data from one array without affecting second array of object.

I have tried JSON parse but it didn't work because I am using drag n drop on data so I wanted to updated specific object passing index.

this.state = {
           listItem: [
            // This data will be static 
                { data: `Text`, content: 'Insert you text here...' },
                {
                    data: `Column`,
                    content: 'Column',
                    columns: [
                        {
                            column: []
                        },
                        {
                            column: []
                        }
                    ]
                }
            ],
           layout:[
           // The data below might be more than 3-4 times repetitive 
            {
                    data: `Column`,
                    content: 'Column',
                    columns: [
                        {
                            column: []
                        },
                        {
                            column: []
                        }
                    ]
                }     
            ]
}

// Set State function I tried recently 
onColumnDrop(e, layoutIndex, colIndex) {

        if (e.removedIndex !== null || e.addedIndex !== null) {

            var stateCopy = Object.assign({}, this.state.layout);
            stateCopy[layoutIndex].columns[colIndex].column = e.payload;
            this.setState({ stateCopy });

        }
    }

So, basically the functionality is as I drag the object from listItem and drop in layout column array so I wanted to setState that dragged object in column[0] or column[1] array so the thing happening is when I keep pushing listItem[0] in column[0] or column[1] array then at the same time its updating in listItem columns, don't know why! but I am super confused.


Solution

  • This sounds very much like you have multiple references to the same object in your code and it is most likely the result of var stateCopy = Object.assign({}, this.state.layout);. This line copies the state only shallowly, which means, that objects and arrays deeper within the state will not be copied, but only the references to the objects will. So you basically end up mutating the original state, when you do stateCopy[layoutIndex].columns[colIndex].colum = e.payload;.

    To avoid this problem, you either have to JSON.parse(JSON.stringify(state)), what seems to be not possible or you have to implement deep copying by your own, where you copy all levels of your state.