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

Kho*_*hoi 97 javascript reactjs

假设我有一个普通对象列表,this.state.list然后我可以使用它来渲染子列表.那么将对象插入的正确方法是什么this.state.list

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

this._list.push(newObject):
this.setState({list: this._list});
Run Code Online (Sandbox Code Playgroud)

这对我来说似乎很难看.有没有更好的办法?

Hea*_*eap 164

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

this.setState({list: this.state.list.concat([newObject])});
Run Code Online (Sandbox Code Playgroud)

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

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

  this.setState(newState);
Run Code Online (Sandbox Code Playgroud)

  • `concat`接受一个数组,所以你需要`this.state.list.concat([newObject])`. (6认同)
  • @Heap好吧,如果你将一个非数组传递给`concat`它会将它包装在一个数组中,但最好自己添加数组来明确:如果你有`[[1,2],[3,4] ]]`并且想要添加`[5,6]`作为下一个元素,你需要做`.concat([[5,6]])`否则你最终会得到`[[1,2] ,[3,4],5,6]`. (6认同)
  • 尽管我很欣赏不变性助手背后的想法(或者我可能最终还是会使用它),但Array.concat肯定比添加另一个库好。 (2认同)

小智 40

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

this.setState((state) => ({ list: state.list.concat(newObj) }))
Run Code Online (Sandbox Code Playgroud)

或者在ES5中:

this.setState(function(state) {
  return {
   list: state.list.concat(newObj)
  }
})
Run Code Online (Sandbox Code Playgroud)

  • 这段代码是如何工作的?push方法将返回一个`NUMBER`,它将在`list`变量上设置 (3认同)
  • @Arian:React将提供只渲染新添加元素所需的DOM变异指令.当然,您新添加的元素不会更改先前元素的呈现方式. (2认同)
  • @Nyalab你不应该在括号中包装函数体吗?就像你现在的例子一样,胖箭头后面的大括号会开始一个块,而不是一个对象.像这样:`this.setState((state)=>({list:state.list.push(newObj)}))` (2认同)

Ash*_*ary 19

2016年更新

使用ES6,您可以使用:

this.setState({ list: [...this.state.list, ...newObject] });
Run Code Online (Sandbox Code Playgroud)

  • `... [newObject]`与`newObject`相同. (5认同)
  • 这不适用于批量更新。请参阅我的示例,网址为http://stackoverflow.com/a/41445812/1998186。 (2认同)

小智 7

来自react文档(https://facebook.github.io/react/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous):

因为this.props和this.state可以异步更新,所以不应该依赖它们的值来计算下一个状态.

所以你应该这样做:

this.setState((prevState) => ({
  contacts: prevState.contacts.concat([contact])
}));
Run Code Online (Sandbox Code Playgroud)