在一个小的React应用程序中,我试图通过一个列表按钮添加删除功能。目前,我正在尝试通过deleteItem函数,它利用数组。拼接原型方法。
然而,我遇到了错误,Too many re-renders. React limits the number of renders to prevent an infinite loop.
。这个错误的原因是什么?这个函数不应该只在单击按钮时调用一次吗?
我该如何解决这个错误?
import "./styles.css";
import React, { useState, Fragment } from "react";
export default function App() {
const [items, setItems] = useState(["first item"]);
const [newItem, setNewItem] = useState("");
const handleSubmit = (event) => {
event.preventDefault();
setItems([newItem, ...items]);
};
const handleChange = (event) => {
setNewItem(event.target.value);
};
const deleteItem = (i) => {
setItems(items.splice(i,1))
}
return (
<div>
<form>
<input type="text" value={newItem} onChange={handleChange} />
<input type="button" value="submit" onClick={handleSubmit} />
</form>
<ul>
{items.map((i) => {
return (
<Fragment>
<li>{i}</li>
<button
onClick= {() => deleteItem(i)}> // Amr recommendation
delete
</button>
</Fragment>
);
})}
</ul>
</div>
);
}
编辑:我已经接受了用户Amr的推荐,并在按钮上添加了一个匿名箭头功能。然而,一个新的问题出现了。我可以删除任何项,直到数组中只存在一个项。最后一项不能删除。为什么会这样?您正在传递onClick处理程序上的函数引用,将其更改为触发删除方法onClick= {()=>deleteItem(i)}>
的箭头函数
第二件事是,当你Map时,你应该为你的父组件添加键通过组件来防止不必要的行为。
和最后一件事是,在您的删除方法中,您正在使用Array.prototype.splice(),它返回将被删除的项目,从项目中,您请求/所需的行为可以通过Array.prototype.filter()方法
实现 const deleteItem = (i) => {
setItems(items.filter((item) => item !== i));
};
这是最终结果,它应该可以正常工作。
import React, { useState, Fragment } from "react";
export default function App() {
const [items, setItems] = useState(["first item"]);
const [newItem, setNewItem] = useState("");
const handleSubmit = (event) => {
event.preventDefault();
setItems([...items, newItem]);
};
const handleChange = (event) => {
setNewItem(event.target.value);
};
const deleteItem = (i) => {
setItems(items.filter((item) => item !== i));
};
console.log(items);
return (
<div>
<form>
<input type="text" value={newItem} onChange={handleChange} />
<input type="button" value="submit" onClick={handleSubmit} />
</form>
<ul>
{items.map((i, idx) => {
return (
<div key={idx}>
<li>{i}</li>
<button onClick={() => deleteItem(i)}>delete</button>
</div>
);
})}
</ul>
</div>
);
}
可以使用以下代码从数组中删除。它复制'items'数组并删除一个项目,然后setstate新数组。它可以防止重新渲染整个组件,对状态副本和setstate最终结果进行操作。
const deleteItem = (i) => {
let newItems=[...items]
newItems.splice(i,1)
setItems(newItems)
};