改变React状态的首选方式是什么?


97

假设我有一个普通对象列表,this.state.list然后可以用来呈现子级列表。那么将对象插入其中的正确方法是什么this.state.list

下面是我认为它将起作用的唯一方法,因为您不能this.state像文档中提到的那样直接更改。

this._list.push(newObject):
this.setState({list: this._list});

这对我来说似乎很丑。有没有更好的办法?


ReactJS中状态数组正确修改的可能重复,请求合并
Brigand

所有这些答案都是关于将元素添加到数组。但是从中删除元素呢?或者只是将阵列完全重置为新阵列?
Augustin Riedinger '16

Answers:


165

concat 返回一个新数组,所以你可以做

this.setState({list: this.state.list.concat([newObject])});

另一个选择是React的不变性助手

  var newState = React.addons.update(this.state, {
      list : {
        $push : [newObject]
      }
  });

  this.setState(newState);

6
concat需要一个数组,所以您需要this.state.list.concat([newObject])
2014年

@BenAlpert在Chrome中为我工作,您是在说这是非标准行为吗?
2014年

6
@Heap好吧,如果将非数组传递给concat它,则会将其包装在数组中,但最好自己添加数组以使其明确:如果[[1,2], [3,4]]要添加并要添加[5,6]为下一个元素,则需要执行.concat([[5,6]])其他操作最后[[1,2], [3,4], 5, 6]
2014年

2
尽管我很欣赏不变性助手背后的想法(而且我可能最终还是会使用它),但Array.concat一定要添加另一个库。
肖恩·厄克特

1
使用从this.state派生的值调用this.setState会使您陷入更新批处理问题。请参阅stackoverflow.com/a/41445812/1998186,该链接链接到显示您将遇到的问题的jsfiddle。
NealeU

40

setState()可以使用函数作为参数来调用:

this.setState((state) => ({ list: state.list.concat(newObj) }))

或在ES5中:

this.setState(function(state) {
  return {
   list: state.list.concat(newObj)
  }
})

2
@Arian:React将执行仅呈现新添加的元素所需的必需DOM突变指令。当然,由于您是新添加的元素,因此不会更改以前的元素的呈现方式。
何塞·布朗

1
这是一个很好的答案,并且感觉比使用conpatting array干净得多,尽管我认为是这样。
马特·斯泰尔斯

2
@Nyalab您不应该将函数体括在括号中吗?在您的示例中,现在,粗箭头后面的括号将开始一个块,而不是一个对象。像这样的东西:this.setState((state) => ({ list: state.list.push(newObj) }))
kumarharsh 2015年

3
此代码如何工作?push方法将返回a NUMBER,它将在list变量上设置
kumarharsh

1
您也可以使用splat:this.setState((state) => ({ list: [...state.list, newObj] }))
amoebe '16


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.