AGrush
AGrush

Reputation: 1167

Updating state inside nested array when mapping the parent

I'm trying to update state inside a nested array with a map function and spread operator, but i don't understand how to get the key in the key/value pair to select a nested object.. There is an arrow in the code to the problematic part.

export default class ControlPanel extends Component {
  state = {
    words: 
    [
      { 
        word: "a",
        id: 1,
        column: 1,
        synonymns: {
          all:[],
          selected:[],
          noneFound: false
        }
      }
    ]
  }
}

updateSynonymnState = (wordId, theSynonymns) => {
  const { words } = this.state

  const newWords = words.map(word => {
    if(word.id == wordId){
      return {...word, synonymns.all: theSynonymns} //<--- synonymns.all is throwing an error, but that is the key that i need.
    } else {
      return word
    } 
  })

  this.setState ({words: newWords})
}

I could map the synonymns from the start but then I would loose the Id of the word which i need to select the right word..

How can I set synonymns.all = theSynonymns inside that words.map function, or is there a different way i should be able to set a nested key/value pair when mapping the parent parameter?

Upvotes: 0

Views: 36

Answers (2)

Zachary Haber
Zachary Haber

Reputation: 11027

Immutable logic with nested values can get very tricky to get right. There are plenty of libraries that focus on that as well. For example: Immer, immutability-helper, immutable-js, and many more.

If you don't want to use another library for your state transitions, then you have to do a bit more work. You need to spread out each of the pieces of state from main object to the part you are modifying.

if (word.id == wordId) {
  return { ...word, synonyms: { ...word.synonyms, all: theSynonymns } }; //<--- synonymns.all is throwing an error, but that is the key that i need.
} else {
  return word;
}

Upvotes: 1

Salmin Skenderovic
Salmin Skenderovic

Reputation: 1720

You have to spread synonymns inside of word as well. Here is an example syntax of doing this:

const words = [{
  word: "a",
  id: 1,
  column: 1,
  synonymns: {
    all: [],
    selected: [],
    noneFound: false
  }
}]

const theSynonymns = ['b'];

const newWords = words.map(word => {
  return {
    ...word,
    synonymns: {
    	...word.synonymns,
      all: theSynonymns
    }
  }
})




console.log(newWords)

Upvotes: 1

Related Questions