Javascript 进入状态数组的正确方法

Javascript 进入状态数组的正确方法,javascript,reactjs,immutability,Javascript,Reactjs,Immutability,我似乎在将数据推入状态数组时遇到问题。 我正试图通过以下方式实现这一目标: this.setState({ myArray: this.state.myArray.push('new value') }) 但我认为这是一种不正确的方法,会导致可变性问题。数组推送返回长度 this.state.myArray.push('new value')返回扩展数组的长度,而不是数组本身 我猜您希望返回的值是数组 不变性 这似乎更像是反应的行为: 永远不要直接改变this.state,因为之后调用setS

我似乎在将数据推入状态数组时遇到问题。 我正试图通过以下方式实现这一目标:

this.setState({ myArray: this.state.myArray.push('new value') })
但我认为这是一种不正确的方法,会导致可变性问题。

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

我猜您希望返回的值是数组

不变性 这似乎更像是反应的行为:

永远不要直接改变this.state,因为之后调用setState()可能会 替换你所做的变异。把这个国家当作 不变的

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

您可以使用方法创建包含新数据的阵列副本:

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

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

您根本不应该操作该状态。至少,不是直接的。如果要更新阵列,则需要执行以下操作

var newStateArray = this.state.myArray.slice();
newStateArray.push('new value');
this.setState(myArray: newStateArray);
直接处理状态对象是不可取的。您还可以查看React的不变性帮助程序


使用es6可以这样做:

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

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

从不建议直接改变状态

在以后的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]
}))
将字符串推送到数组的开头

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]
}))
将对象推送到数组的末尾

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]
}))
将对象推送到数组的开头

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]
}))

这段代码对我有用:

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

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

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

在这里,您不能像这样将对象推送到状态数组。你可以像在普通阵列中一样推进。 在这里你必须设置状态

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

使用功能组件和反应挂钩

const [array,setArray] = useState([]);
最后的推送值:

setArray(oldArray => [...oldArray,newValue] );
在乞讨时推送价值:

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

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


fetch('http://localhost:8080然后(json={this.setState({mystate[…this.state.mystate,json]})}

使用react钩子,您可以按照以下方式执行

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


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

我想现在回答这个问题有点晚了,但是对于那些新手来说,他们的反应是

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


请参见此示例:

我也这样做了,有两种情况myArray可以有值,但不会有值。因此,如果它已经有了值,那么它工作得非常好。但没有数据..它不会用“新值”更新状态。任何soln?它应该与任何数组一起工作,不管它是否有值,它都将被解构。也许其他地方出了什么问题。你能展示一下你的代码吗?嗨,请参考我在@Tamas answer下的评论。这只是控制台中的一个示例。我尝试myArray:[…this.state.myArray,'new value']来更新我的状态数组。但它只包含最后一个值。请告诉我解决方案好吗?@Johncy我不确定您的问题是否与此问题有关,请尝试提出单独的问题并描述预期的行为,我将尝试帮助您。根据React文档:“因为
this.props
this.state
可能会异步更新,所以您不应该依赖它们的值来计算下一个状态。“在修改数组的情况下,由于数组已作为
this.state
的属性存在,并且需要引用其值来设置新值,因此应使用
setState()
的形式,该形式接受具有先前状态的函数作为参数。示例:
this.setState(prevState=>({myArray:[…this.state.myArray,'新值']}))见:我相信这个答案是正确的,尽管我想知道为什么我们不能在状态上操作,即为什么它不可取。经过一番挖掘,我发现以下内容有助于填补缺少的信息,本教程还使用
.slice()
创建新数组并保持不变性。谢谢你的帮助。欢迎使用堆栈溢出!请不要只回答源代码。试着提供一个关于你的解决方案如何工作的很好的描述。请参阅:。谢谢,我试过了,但没用。这是我的代码
fetch(`api.openweathermap.org/data/2.5/forecast?q=${this.searchBox.value+KEY}')。然后(response=>response.json())。然后(data=>{this.setState({reports:this.state.reports.push.apply(this.state.reports,data.list)})this.state={reports=[]}
…请告诉我我在做什么wrong@Hamid侯赛因波里用了这个答案。它还可用于在数组中预编:
this.setState((prevState)=>({myArray:[values,…prevState.myArray],}))这是一种比公认的答案好得多的方法,而且它是否符合React文档建议的方式。肯定是+1,因为其他答案没有遵循最新的指导原则,即在自身改变状态时使用回调。如何在状态数组中添加另一个数组对象?当我这样做时
console.log(this.state.myArray)
它总是落后一个。知道为什么吗?@Si8哦,不幸的是,我没有太多使用React。但是文档说:
setState()
将组件状态的更改排入队列,并告诉React需要使用更新的状态重新呈现此组件及其子组件。所以我猜它只是在设置之后的那一刻没有更新。你能