Skip to content Skip to sidebar Skip to footer

How To Use Reduce Function In A Nested State Object In Reactjs?

My state value is this.state = { content: { text: { tag1: { line: 'data1' } tag2: { line: 'data2'

Solution 1:

Here you are:

this.setState(prevState => {
    return {
        content: {
            ...prevState.content,
            text: Object.keys(prevState.content.text).reduce((newTexts, key) => {
                return {
                    ...newTexts,
                    [key]: {
                        line: "changed text"
                    }
                }
            }, {})
        }
    }
});

Solution 2:

You should you setState with a function so you don't change state directly.

this.setState(prevState => {        
    for(let k in prevState.content.text){
        prevState.content.text[k].line = "changed";
    } 
    return {content: prevState.content}
}

Edit:

I'm not sure if changing prevState directly is a good thing (please some one correct me), but you can also do

this.setState(prevState => {   
    let changedState = {...prevState}     
    for(let k in changedState.content.text){
        changedState.content.text[k].line = "changed";
    } 
    return {content: changedState.content}
}

Edit:

As said in the comments, {...prevState} is going to be a shallow copy and it can still change the state directly. One solution to this is use lodash cloneDeep

Solution 3:

I think using for..in will be better.

const state = {
    content: {
        text: {
            tag1: {
                line: "data1"
            },
            tag2: {
                line: "data2"
            }
        }
    }
}

for(let k in state.content.text){
  state.content.text[k].line = "changed";
} 
console.log(state)

Solution 4:

I don't think Array#prototype#reduce would be a fit.

You can use a plain modern for...of loop with Object.entries and do this:

const state = {
    content: {
        text: {
            tag1: {
                line: "data1"
            },
            tag2: {
                line: "data2"
            }
        }
    }
};

for (const obj ofObject.entries(state.content.text)) {
	obj[1].line = 'Changed text';
}

console.log(state);

For acheiving an immutable state you can do Object.assign before mutating the new object's properties.

const state = {
  content: {
    text: {
      tag1: {
        line: "data1"
      },
      tag2: {
        line: "data2"
      }
    }
  }
};

// Create a new object from an existing objectconst newState = Object.assign(state, {});

Object.entries(newState.content.text).forEach(x => {
  x[1].line = 'Changed text';
});

console.log(newState);

Post a Comment for "How To Use Reduce Function In A Nested State Object In Reactjs?"