Javascript 如何向列表中添加新元素?
我试图向列表中添加一个新的数组元素,更新一个属性(id)。我想使它比数组的长度多1。 但我得到了一些奇怪的输出,每添加一个新对象。所有元素都将获得array.length+1值 我用Javascript 如何向列表中添加新元素?,javascript,arrays,reactjs,Javascript,Arrays,Reactjs,我试图向列表中添加一个新的数组元素,更新一个属性(id)。我想使它比数组的长度多1。 但我得到了一些奇怪的输出,每添加一个新对象。所有元素都将获得array.length+1值 我用let,const对这段代码做了几次修改,甚至直接对this.state.produktsToBuy进行操作,每次都得到相同的输出 handleAddToShop = (produktToBuy) => { const id = this.state.produktsToBuy.length+1; pr
let
,const
对这段代码做了几次修改,甚至直接对this.state.produktsToBuy
进行操作,每次都得到相同的输出
handleAddToShop = (produktToBuy) => {
const id = this.state.produktsToBuy.length+1;
produktToBuy.id = id + 1;
const produktsToBuy = this.state.produktsToBuy;
produktsToBuy.push(produktToBuy);
this.setState({produktsToBuy});
};
我应该得到输出为1,2,3,4,5,6,7
但是最后我得到了7,7,7,7,7,7,确保你没有直接改变状态。在JS中,对象是引用类型。当您将
this.state.produktsToBuy
分配给const produktsToBuy
并将某个内容推送到produktsToBuy
时,实际上是推送到原始的this.state.produktsToBuy
,然后修改状态
您可以使用排列运算符(…
)创建状态的浅层副本(produktsToBuy
):
类应用程序扩展了React.Component{
状态={
项目:[
{名称:“试验项目1”,价格:4.99},
{名称:“试验项目2”,价格:7.99},
{名称:“试验项目3”,价格:19.99}
],
produktsToBuy:[]
};
HandleadToShop=(ProduktoBuy)=>{
此.setState((上一个)=>({
produktsToBuy:[
…prev.produktsToBuy,
{
…ProduktoBuy,
id:prev.produktsToBuy.length+1
}
]
}));
};
render(){
返回(
{this.state.items.map((item)=>(
{item.name}
${item.price}
this.handleAddToShop(item)}>Add
))}
{JSON.stringify(this.state.produktsToBuy,null,2)}
);
}
}
ReactDOM.render(,document.getElementById('root'))代码>
如果除了produktsToBuy之外还有其他内容,那么您应该维护所有以前的状态。此外,如果要设置的任何内容都依赖于以前的状态(通常情况下),则始终需要setState的函数形式。而且,正如Zsolt所说,你永远不会在React中直接改变状态。以下是我的答案(与@Zsolt Meszaros非常相似)。注意:.concat创建了一个新的数组,因此我们不必担心对原始数组进行变异
什么是produktsToBuy.pu在此处输入代码(produktToBuy)代码>?啊,好吧,这是produktsToBuy.push(produktToBuy)代码>。你能在你的帖子中修复它吗?请格式化你的代码以便我们可以阅读它!:好的,但我想更新状态。它只是一个没有后端的应用程序,我希望立即看到更改上面的代码更新状态,但您应该始终使用this.setState
。我刚刚在上面添加了一个实时代码段,您可以运行它并检查结果。
handleAddToShop = (produktToBuy) => {
this.setState((prevState) => {
const { produktsToBuy } = prevState;
return {
...prevState,
produktsToBuy: produktsToBuy.concat([
{
...produktToBuy,
id: produktsToBuy.length + 1,
},
]),
};
});
};