正确推入状态数组的方法

时间:2016-05-25 11:08:37

标签: javascript reactjs immutability

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

this.setState({ myArray: this.state.myArray.push('new value') })

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

13 个答案:

答案 0 :(得分:91)

使用es6可以这样做:

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

Spread syntax

答案 1 :(得分:78)

数组推送返回长度

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

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

我猜你希望返回的值是数组。

不变性

这似乎是React的行为:

  

不要直接改变this.state,因为之后调用setState()可能   替换你所做的突变。把它当作状态对待   不可变的。

     

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

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

var joined = this.state.myArray.concat('new value');
this.setState({ myArray: joined })

答案 2 :(得分:38)

  

从不建议直接更改状态。

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

将字符串推到数组的末尾

this.setState(prevState => ({
  myArray: [...prevState.myArray, "new value"]
}))

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

this.setState(prevState => ({
  myArray: ["new value", ...prevState.myArray]
}))

将对象推到数组的结尾

this.setState(prevState => ({
  myArray: [...prevState.myArray, {"name": "object"}]
}))

将对象推送到数组的开头

this.setState(prevState => ({
  myArray: [ {"name": "object"}, ...prevState.myArray]
}))

答案 3 :(得分:12)

使用函数式组件和 React Hooks

const [array,setArray] = useState([]);

最后推送值:

setArray(oldArray => [...oldArray,newValue] );

在乞讨时推送价值:

setArray(oldArray => [newValue,...oldArrays] );

答案 4 :(得分:11)

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

this.setState({ myArray: this.state.myArray.concat('new value') })

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

答案 5 :(得分:9)

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

var newStateArray = this.state.myArray.slice();
newStateArray.push('new value');
this.setState(myArray: newStateArray);

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

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

答案 6 :(得分:9)

在这里您不能将对象推入这样的状态数组。您可以按自己的方式在常规数组中进行推送。 在这里,您必须设置状态

this.setState({ 
     myArray: [...this.state.myArray, 'new value'] 
})

答案 7 :(得分:5)

使用react hooks,你可以按照以下方式进行

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


setCountries((countryList) => [
        ...countryList,
        "India",
      ]);

答案 8 :(得分:1)

此代码对我有用:

fetch('http://localhost:8080')
  .then(response => response.json())
  .then(json => {
  this.setState({mystate: this.state.mystate.push.apply(this.state.mystate, json)})
})

答案 9 :(得分:1)

通过以下方式,我们可以检查和更新对象

this.setState(prevState => ({
    Chart: this.state.Chart.length !== 0 ? [...prevState.Chart,data[data.length - 1]] : data
}));

答案 10 :(得分:0)

React-Native

如果您还希望您的UI(即您的flatList)是最新的,请使用PrevState: 在下面的示例中,如果用户单击按钮,它将向列表(在模型和UI中)添加一个新对象

data: ['shopping','reading'] // declared in constructor
onPress={() => {this.setState((prevState, props) => {
return {data: [new obj].concat(prevState.data) };
})}}. 

答案 11 :(得分:0)

您违反了 React 原则,您应该克隆旧状态然后将其与新数据合并,您不应该直接操作您的状态, 你的代码应该是这样的

fetch('http://localhost:8080').then(response => response.json()).then(json ={this.setState({mystate[...this.state.mystate, json]}) })

答案 12 :(得分:0)

我想这对答案来说有点晚了,但对于那些新的反应

你可以使用这个叫做 immer 的小包

看这个例子:https://immerjs.github.io/immer/produce