我向用户展示了一个预先填充了数据的可编辑表,并希望包含一个'丢弃更改'按钮,该按钮将调用handleReset()函数来恢复'活动'数据集(一个对象数组)到它的原始状态。
我所采取的方法是将数据读取到一个名为'dataBackup'的变量中,也读取到一个名为'dataWorking'的状态变量中。其想法是,用户编辑将应用于dataWorking,而dataBackup将保持不变,并可用于在需要时重置dataWorking。但是,当编辑表时,修改同时应用于和。变量!
我是React的新手,我不理解这种行为。我也不确定我选择的方法是否是处理此功能的最佳方法,因为我还没有找到任何类似的示例。感谢一些指点,并添加了我的样例代码属于演示发生了什么。
import {useState} from 'react';
const budgetData =
[
{ index: 0, category: 'Housing', item: 'Mortgage', amount: 650.99 },
{ index: 1, category: 'Housing', item: 'Insurance', amount: 275.50 },
{ index: 2, category: 'Utilities', item: 'Hydro', amount: 70.00 }
];
function UpdateBudget() {
const dataBackup = [...budgetData];
const [dataWorking, setDataWorking ] = useState(budgetData);
const handleChange = ( (e, row) => {
let selectedData = [...dataWorking];
const {name, value} = e.target;
selectedData[row][name] = value;
setDataWorking(selectedData);
});
const handleReset = ( (e) => {
setDataWorking(dataBackup);
});
return (
<div>
<table>
<thead>
<tr>
<th>Category</th> <th>Item</th> <th>Amount</th>
</tr>
</thead>
<tbody>
{ dataWorking.map( (row) => (
<tr key={row.index}>
<td> <input value={row.category} name="category" onChange={(e) => handleChange(e, row.index)}/> </td>
<td> <input value={row.item } name="item" onChange={(e) => handleChange(e, row.index)}/> </td>
<td> <input value={row.amount } name="amount" onChange={(e) => handleChange(e, row.index)}/> </td>
</tr>
))
}
</tbody>
</table>
<div>
<button onClick={ (e) => handleReset (e)}> Discard Changes </button>
</div>
<div style={{ marginTop: 20, fontSize: 10 }}> * budgetData {budgetData.length} * {JSON.stringify(budgetData)} </div>
<div style={{ marginTop: 20, fontSize: 10 }}> * dataWorking {dataWorking.length} * {JSON.stringify(dataWorking)} </div>
<div style={{ marginTop: 20, fontSize: 10 }}> * dataBackup {dataBackup.length} * {JSON.stringify(dataBackup)} </div>
</div>
);
}
export default UpdateBudget;
你看到dataBackup
更新后,你的状态改变是因为你复制数组内的对象引用。如果您想拥有一个完全未引用的budgetData
副本,最简单的解决方案是
将使用JSON
方法(但我建议研究一下对象的深度复制是什么):
const dataBackup = JSON.parse(JSON.stringify(budgetData))
一般来说,存储不会导致UI呈现的值的最佳实践是使用useRef
:
const dataBackup = React.useRef(JSON.parse(JSON.stringify(budgetData)))
// then access it like that
dataBackup.current
另一件事,在你的handleChange
中,你实际上是在改变状态,这应该避免:
selectedData[row][name] = value;
理想情况下,你应该拼接和扩展这些对象,这样你就不会直接修改状态,或者使用一些深度复制方法。