如何在深层嵌套的对象中保存状态?

时间:2019-03-22 09:03:43

标签: javascript reactjs

我有一个处于状态存储的JSON文件。现在,我需要更新该文件中的值。当我使用setState时,它不会保存任何内容。 this.state.data是一个包含4个对象的数组。我在哪里做错了?

这是我的状态:

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

现在我正在尝试将值保存到数据中

this.setState({
      [data[index].settings[idSettings].settings._init_[idMessageContent]
        .message_content]: newValue,
    })

2 个答案:

答案 0 :(得分:1)

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

而你所做的是

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

这表示您为状态设置了一个名称为[oldvalue]的新属性。您应该将data克隆到一个新对象并对该对象进行突变。然后将整个新对象分配给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})

答案 1 :(得分:0)

如果您想完全避免突变,我可以为您提供以下几种解决方案。

一种解决方案是像这样手动分布对象的每一层。

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

但是它看起来非常复杂且难以理解。

我更喜欢的解决方案是编写自己的实用程序函数为您执行此操作,或者您可以使用已经存在且经过测试的函数,例如Ramda.js中的assocPath或其他库(例如Lodash等)中的类似函数。 )

this.setState(R.assocPath([ 'users', 'john', 'status', ...], newPropValue))