简体   繁体   中英

Create a immutable copy of a property

I have a situation where I want to make a unchangeable copy of a property to restore state to its original... well state.

I have a array of group objects.
Inside each group i have and array of items .
When I make the copy bellow everything is fine.

I start by doing this.

componentDidMount(){
    // originalGroups = Object.assign([], this.props.modalitygroups);
    originalGroups = JSON.parse(JSON.stringify(this.props.modalitygroups));
},

I have tried both of the statements above, but have read that the current active one makes a true deep copy of a object. Needles to say it does copy it properly.

I then have THIS search feature to search for items in the groups and items.

_searchFilter:function(search_term){
    this.setState({modalitygroups:originalGroups});
    let tempGroups = Object.assign([], this.state.modalitygroups);

    if(search_term !== ''){
        for (let x = (tempGroups.length) - 1; x >= 0; x--)
        {
            console.log("originalGroups",x,originalGroups);

            for (let i = (tempGroups[x].items.length) - 1; i >= 0; i--)
            {
                if(!tempGroups[x].items[i].description.toLowerCase().includes(search_term.toLowerCase())){
                    tempGroups[x].items.splice(i,1);
                }
            }
            if(tempGroups[x].items.length === 0){
                tempGroups.splice(x, 1);
            }
        }
        this.setState({modalitygroups:tempGroups});
    }
},

So I start of by restoring the original state to enable searching through everything. The search feature loops though each groups and within each group loop I loop through each item deleting items that dont contain the search phrase.
After looping through each item, if no item remain in the group, I remove that group from the group array aswell.

This works well first time arround.

But when I start searching for a new item, I find that the originalGroups has changed aswell. The previous deleted items has been removed from the unchangable copy aswell and I dont know why. Where and why does it change my safe copy?

Hope this makes sense.

 const state = { property1: 42 }; const originalGroups = Object.freeze(state); originalGroups.property1 = 33; // Throws an error in strict mode console.log(originalGroups.property1); // expected output: 42 

Essentially ReactJS is still javascript afterall, so you can apply Object.freeze to save a copy of state

So modality groups contains original groups? This is hard to follow... Instead of 'saving' the original groups, I'd leave this.props.modalitygroups alone and copy to a filteredGroups of the state. You can reload that from the props that you never change.

In your filter function when you do let tempGroups = Object.assign([], this.state.modalitygroups); that should probably be where you use json to create a deep copy. That is filling the new array with the same group references in the old array, so you are modifying the same group instance in the original.

_searchFilter:function(search_term){
    // deep copy
    let tempGroups = JSON.parse(JSON.stringify(this.props.modalitygroups));

    if(search_term !== ''){
        for (let x = (tempGroups.length) - 1; x >= 0; x--)
        {
            console.log("originalGroups",x,originalGroups);

            for (let i = (tempGroups[x].items.length) - 1; i >= 0; i--)
            {
                if(!tempGroups[x].items[i].description.toLowerCase().includes(search_term.toLowerCase())){
                    tempGroups[x].items.splice(i,1);
                }
            }
            if(tempGroups[x].items.length === 0){
                tempGroups.splice(x, 1);
            }
        }
        this.setState({modalitygroups:tempGroups});
    }
},

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM