我正在学习将钩子与react结合使用,并尝试创建一个简单的网站,在其中写入2个值并将其添加到列表中。列表中的每个项目都有一个删除按钮。
由于某种原因,当我添加两行以上时,问题似乎开始了。例如,如果我添加2行,然后在开始加载的旧行上按Delete键-它要么删除它们,要么用与新行相同的值替换它们。
不知道我在做什么错,因为删除有效,直到我直接在开始处添加+2行以上。
Kinda很难解释,但是我创建了一个沙箱,可以更容易地看到问题。
删除和添加功能:
const deleteRow = async (index, e) => {
var data = testArr;
data.splice(index, 1);
setTestArr([...data]);
};
const addRow = async e => {
var obj = {
id: 1,
start: inputFrom,
stop: inputTo
};
var data = testArr;
data.push(obj);
setTestArr([...data]);
};
映射功能:
{testArr.map((item, index) => (
<div key={item.id} className="col-12">
<div className="control-group mb-1">
<span className="mr-2">
{item.start} - {item.stop}
</span>
<input
type="button"
className="btn btn-light"
value="Delete row"
onClick={e => deleteRow(index, e)}
/>
</div>
</div>
))}
沙箱:
答案 0 :(得分:3)
首先,您可能不使用var
关键字,而是使用ES const
|| let
,以确保您不会因为JS吊起而遇到意外的副作用,
秒-
var data = testArr;
data.splice(index, 1);
是非法移动,因为data
与状态在内存中没有不同,它只是指针,因此您可以在setState
之外修改状态
第一个选择是浅拷贝状态
let data = [...testArr];
或直接在setState
// delete
setTestArr(prev => prev.filter((item, i) => i != index ));
// add
setTestArr(prev => [...prev, obj]);
答案 1 :(得分:3)
尝试使用以下功能:
const deleteRow = async (index, e) => {
var data = [...testArr];
data.splice(index, 1);
setTestArr(data);
};
和
const addRow = async e => {
setTestArr([{
id: 1,
start: inputFrom,
stop: inputTo
},...testArr]);
};
我建议您使用useCallback来定义它们。
答案 2 :(得分:3)
我将使用此删除功能:
const deleteRow = (index, e) => {
setTestArr(prev => {
return prev.filter((e, i) => i !== index);
});
};
代替过滤数据,只是过滤掉我们不需要的索引。