正确推入状态数组的方法

Ilj*_*lja 91 javascript immutability reactjs

我似乎在将数据推送到状态数组时遇到问题.我试图通过这种方式实现它:

this.setState({ myArray: this.state.myArray.push('new value') })
Run Code Online (Sandbox Code Playgroud)

但我认为这是不正确的方式并导致可变性问题?

Ali*_*ich 128

使用es6可以这样做:

this.setState({ myArray: [...this.state.myArray, 'new value'] }) //simple value
this.setState({ myArray: [...this.state.myArray, ...[1,2,3] ] }) //another array
Run Code Online (Sandbox Code Playgroud)

传播语法

  • 根据React docs:“由于`this.props`和`this.state`可能是异步更新的,因此您不应该依赖它们的值来计算下一个状态。” 在修改数组的情况下,由于数组已经作为this.state的属性存在,并且您需要引用其值以设置新值,因此您应该使用setState()的形式来接受函数以先前的状态作为参数。示例:`this.setState(prevState =>({myArray:[... this.state.myArray,'new value']})));`参见:https://reactjs.org/docs/state-and- lifecycle.html#state-updates-may-as-asynchronous (4认同)

Már*_*más 106

数组推送返回长度

this.state.myArray.push('new value') 返回扩展数组的长度,而不是数组本身.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push

我猜你期望返回的值是数组.

不变性

这似乎是React的行为:

永远不要直接改变this.state,因为之后调用setState()可能会替换你所做的突变.把this.state看作是不可变的.

https://facebook.github.io/react/docs/component-api.html

我想,你会这样做(不熟悉React):

var joined = this.state.myArray.concat('new value');
this.setState({ myArray: joined })
Run Code Online (Sandbox Code Playgroud)


Hem*_*ari 70

永远不建议直接改变国家.

后来的React版本中推荐的方法是在修改状态时使用更新程序功能以防止竞争条件:

将字符串推送到数组的末尾

this.setState(prevState => ({
  myArray: [...prevState.myArray, "new value"]
}))
Run Code Online (Sandbox Code Playgroud)

将字符串推送到数组的开头

this.setState(prevState => ({
  myArray: ["new value", ...prevState.myArray]
}))
Run Code Online (Sandbox Code Playgroud)

将对象推送到数组的末尾

this.setState(prevState => ({
  myArray: [...prevState.myArray, {"name": "object"}]
}))
Run Code Online (Sandbox Code Playgroud)

将对象推送到数组的开头

this.setState(prevState => ({
  myArray: [ {"name": "object"}, ...prevState.myArray]
}))
Run Code Online (Sandbox Code Playgroud)

  • 这是比公认的答案更好的方法,并且按照 React 文档推荐的方式进行。 (2认同)
  • 绝对+1,因为其他答案不遵循使用回调(如果状态自身发生变化)的最新指南。 (2认同)

Pan*_*iss 24

函数式组件和 React Hooks

const [array,setArray] = useState([]);
Run Code Online (Sandbox Code Playgroud)

最后推送值:

setArray(oldArray => [...oldArray,newValue] );
Run Code Online (Sandbox Code Playgroud)

在乞讨处推送价值:

setArray(oldArray => [newValue,...oldArrays] );
Run Code Online (Sandbox Code Playgroud)


Sac*_*ala 16

在这里,您不能像这样将对象推送到状态数组。您可以在普通数组中按自己的方式推送。在这里你必须设置状态,

this.setState({ 
     myArray: [...this.state.myArray, 'new value'] 
})
Run Code Online (Sandbox Code Playgroud)


Chr*_*oph 12

你根本不应该操作这个州.至少,不是直接的.如果你想更新阵列,你会想做这样的事情.

var newStateArray = this.state.myArray.slice();
newStateArray.push('new value');
this.setState(myArray: newStateArray);
Run Code Online (Sandbox Code Playgroud)

直接处理状态对象是不可取的.您还可以查看React的不变性助手.

https://facebook.github.io/react/docs/update.html

  • 我相信这个答案是正确的,虽然我想知道为什么我们不能对状态进行操作,即为什么它不可取.经过一番挖掘后,我发现了以下[反应教程 - 为什么不可变性很重要](https://reactjs.org/tutorial/tutorial.html#why-immutability-is-important),这有助于填写缺失的信息和本教程还使用`.slice()`来创建一个新数组并保持不变性.谢谢您的帮助. (4认同)

Gin*_*den 11

您可以使用.concat方法使用新数据创建数组的副本:

this.setState({ myArray: this.state.myArray.concat('new value') })
Run Code Online (Sandbox Code Playgroud)

但是要小心.concat传递数组时方法的特殊行为- [1, 2].concat(['foo', 3], 'bar')会导致[1, 2, 'foo', 3, 'bar'].


Raj*_*sit 7

使用反应钩子,您可以按照以下方式进行

const [countryList, setCountries] = useState([]);


setCountries((countryList) => [
        ...countryList,
        "India",
      ]);
Run Code Online (Sandbox Code Playgroud)