简体   繁体   中英

How to change state inside nested object in React

Hi i have parrent and child component. Parrent component is receiving data from server. This data are saved in state.data. Now, when i do action in child component, it should be call method from parrent controller. This is working now. Problem is inside this method which i am calling. I am receiving id as parameter. This data in parrent have list of items (packages) and every item has id. I need to update only one of them by id (or other way i don't know right way). Please how i can do it? I need to update isOpen state only that one item i open by clicking on button in child component My method (but i am not sure if i started to do this right way), i stucked on this problem for while:

changeIsOpenState(typeOfPart: Number, id: Number) {
        console.log(this.state.data.packages);
        const selectedObject = this.state.data.packages.filter((obj) => {
            const val= (obj.id === id) ? obj : false;
            return val;
        });
    }

Array of data i want update (isOpen property).

我需要更改的数据

what about immutably? I think u can use dot-prop-immutable package in this way:

const state = {
  packages: [
    { isOpen: false, id: 1 },
    { isOpen: false, id: 2 },
    { isOpen: false, id: 3 }
  ]
};
const index = state.packages.findIndex(obj => obj.id === 3);
const newState = dotProp.set(state, `packages[${index}].isOpen`, true);

you could do it the ol' way:

changeIsOpenState(typeOfPart: Number, id: Number) {
  // Copy the packages so you won't mumtate your state directly
  const packages = Object.assign({}, ...this.StaticRange.data.packages);

  // Get the package to edit and its index in the packages object
  let packageIndex;
  let packageToEdit;

  for(let i = 0; i <= packages.length; i++){
    if(packages[i].id === id){
      packageIndex = i;
      packageToEdit = packages[i];
      packageToEdit.isOpen = true
    }
  }
  packages[packageIndex] = packageToEdit;
  setState({...this.state, data:{...this.state.data, packages}});
}

I did it like this: 1.I copy current data to another variable 2.Filter data by id 3.Save array key of item with same id 4. Change cloned value with negation 5. save new data to state

 changeIsOpenState(typeOfPart: Number, id: Number) {
        const subjectDataCopy = cloneDeep(this.state.data);
        const keys = [];
        subjectDataCopy.packages.filter((obj, key) => {
            if (obj.id === id) {
                keys.push(key);
            }
        });
        subjectDataCopy.packages[keys[0]].isOpen = !subjectDataCopy.packages[keys[0]].isOpen;
        this.setState({data: subjectDataCopy});
    }

If there is better option to do this please let me know:)

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