ReactJS:更新嵌套状态对象属性,而无需使用setState()

时间:2019-04-30 23:29:29

标签: javascript reactjs

在组件状态下更改嵌套对象的多个属性值时,我试图应用最佳实践。

我的组件代码当前如下所示:

class App extends Component {
  state = {
    object: {
      a: 10,
      b: 7,
      c: 12,
    }
  }
  render() {
    return (
      <div>
        <button onClick={this.setState({ object: { a: 5 }})}>change value a </button>
        <button onClick={this.setState({ object: { b: 2 }})}>change value b </button>
        <button onClick={this.setState({ object: { c: 3 }})}>change value c </button>
      </div>
      <p>{this.state.object.a}</p>
      <p>{this.state.object.b}</p>
      <p>{this.state.object.c}</p>
    );
  }
}

在单击任何按钮之前,您会看到三个按钮,然后在页面上依次显示分别为10712的段落。

单击第一个标记为“更改值a”的按钮后,值bc在我的组件状态对象中被破坏,这仅导致显示5的值。如果单击第二个按钮,则仅显示2,并且道具ac消失了。

我了解这种行为,但是我想知道解决它的最佳方法。我想保留它,以便所有值都显示出来,并能够在其他值保留的同时以任何顺序更新它们。

我也很确定我直接在改变状态,我知道这是不好的做法。在这种情况下,我只是不知道正确的做法。

2 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是在嵌套...上使用传播object运算符,以将{ a: 5 }的更新与{{1}的先前状态合并}字段:

object

有几种方法可以将其与// Create a new state object, with updated value of "5" for nested field "object.a" { object: { ...state.object, a: 5 }} 合并-一种简单的方法是通过传递给setState()的回调:

setState()

这允许您合并嵌套的this.setState(state => { object: { ...state.object, a: 5 }}) 的先前状态,并合并状态,例如object上的{ a : 5 },而无需完全替换其中的所有嵌套object值您的状态。

对于渲染功能,您可以像这样更新渲染结果:

object

答案 1 :(得分:1)

首先要回答您所说的话, “我正在直接改变状态”

由于您正在调用this.setState(),因此您不是直接在改变状态。

由于您要更新object: {}的特定部分,因此可以如下使用扩展语法或Object.assign()

this.setState({ object: { ...this.state.object, a: 5 } })

this.setState({ object: Object.assign({}, this.state.object, { a: 5 }) })

由于您在this.setState()中呼叫了render,因此您将获得Maximum call stack exceeded error

我可以想到四种解决方法,我将展示其中两种。

  1. 将您的调用提取到类方法中,然后将引用传递给 点击事件处理程序。
  2. 将此onClick={this.setState({ object: { c: 3 }})}更改为onClick={() => this.setState({ object: { c: 3 }})}