简体   繁体   中英

reactJs setState change property on object within an array

I'm a little bit stuck. I try to override a certain object from an array with another object from another array :

onStepsLayoutChange = (layout) => {
        console.log("The new layout is", layout); //Array
        this.setState((prevState) => ({
            layout: layout,
            stepsData: prevState.stepsData.map(step => {
                layout.map(l => {
                  if(step.identifier === parseInt(l.i)){
                      console.log("Match", l, step); // "l" is not empty and actually matches only if "id" is identical
                      return {
                          ...step,
                          layout: l //I want to override "layout" with the current layout "l"
                      }
                  }
                });
                return step
            })
        }), () => console.log("LayoutChange:", this.state.layout, this.state.stepsData)); // "layout" in each step is empty
    };

Whats my fail in this case?

If you stepsData must be an array of arrays you forget one return:

onStepsLayoutChange = (layout) => {
        console.log("The new layout is", layout); //Array
        this.setState((prevState) => ({
            layout: layout,
            stepsData: prevState.stepsData.map(step => {
                return layout.map(l => { //here <---
                  if(step.identifier === parseInt(l.i)){
                      console.log("Match", l, step); // "l" is not empty and actually matches only if "id" is identical
                      return {
                          ...step,
                          layout: l //I want to override "layout" with the current layout "l"
                      }
                  }
                });
                return step
            })
        }), () => console.log("LayoutChange:", this.state.layout, this.state.stepsData)); // "layout" in each step is empty
    };

Issue is, you are missing the default behaviour of #array.map . For each array value map will return some value by default undefined . You are running map inside map, So the final value that stepData will have is:

[[...], [...], [....] ....]

Instead of using nested map, use #array.findIndex or #array.find and return the value.

Write it like this:

stepsData: prevState.stepsData.map(step => {
    let index;
    index = layout.findIndex(l => step.identifier === parseInt(l.i));

    if(index >= 0){
        return {
            ...step,
            layout: layout[index]
        }
    }

    return step;
})

Check this snippet:

 let a = [1,2,3,4,5]; let b = [2,3]; let result = a.map(i => { return b.map(j => { if(i === j) return 0; }) return i; }) console.log(result); 

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