0

I have a JSON file that stored in state. Now I need to update a value in that file. When I use setState it doesn't save anything. this.state.data is an array that contains 4 objects. Where I'm doing a mistake?

this is my state:

constructor(props) {
    super(props)
    this.state = {
      data: null,
    }
  }

Now I'm trying to save the value in data

this.setState({
      [data[index].settings[idSettings].settings._init_[idMessageContent]
        .message_content]: newValue,
    })
matiit
  • 7,969
  • 5
  • 41
  • 65
Yerlan Yeszhanov
  • 2,149
  • 12
  • 37
  • 67

2 Answers2

1
[data[index].settings[idSettings].settings._init_[idMessageContent].message_content] ~ [oldValue]

And what you did is

this.setState({[oldValue]: newValue})

This means you set a new property with the name is [oldvalue] for the state. You should clone data to a new object and mutate that object. Then assign the whole new object to state

// Deep clone the object
const newData = JSON.parse(JSON.stringify(this.state.data))
// Mutating the new object
newData[index].settings[idSettings].settings._init_[idMessageContent].message_content = newVlaue
// Assign the new object to state
this.setState({data: newData})
bird
  • 1,872
  • 1
  • 15
  • 32
0

If you want to avoid mutation at all i can suggest you several solutions listed below.

One solution is to manually spread every layer of object like so.

this.setState((prevState) => ({
  users: {
    ...prevState.users,
    john: {
      ...prevState.users.john,
      status: {
        ...prevState.users.john.status
        /* ... */
      } 
    }
  }
}))

But it seems very complicated and unreadable.

The solution that I prefer is to write own utility function to do it for you OR you can use already existing and well-tested function like assocPath from Ramda.js or similar from other libraries (e.g. Lodash etc.)

this.setState(R.assocPath([ 'users', 'john', 'status', ...], newPropValue))
lankovova
  • 1,396
  • 8
  • 15