拼接和设置状态后奇怪的 return 数据
Weird return of data after splice and setstate
这里用codesandbox模拟
https://codesandbox.io/embed/epic-nash-mxteu?fontsize=14&hidenavigation=1&theme=dark
当我从创建的动态行中删除一行时,我遇到了一个奇怪的行为。
我删除了带有 2 b 的行。如您所见,控制台日志具有正确的数据,而 UI 显示错误的数据。这意味着该功能运行良好但不知何故显示不正确。
有人知道为什么吗?提前致谢
截图
删除行之前
删除行后
源代码
const [gavRows, setGAVRows] = useState([]);
const handleGAVAddRow = async () => {
try {
const item = {
gav_field: '',
gav_value: ''
};
setGAVRows([...gavRows, item]);
} catch (error) {
console.log('error', error)
}
};
const handleGAVRemoveSpecificRow = (idx) => {
console.log('idx', idx)
const tempRows = [...gavRows];
console.log('tempRows', tempRows)
tempRows.splice(idx, 1);
setGAVRows(tempRows)
};
const handleGAVChange = async (idx, e) => {
const { name, value } = e.target;
var tempRows = [...gavRows];
tempRows[idx][name] = value;
setGAVRows(tempRows)
};
<table className="customgav_section">
<tbody>
{
gavRows.map((item, idx) => {
console.log('map idx', idx, item)
return (
<tr key={idx}>
<td>
<Input type="text"
name="gav_field" id="gav_field"
value={gavRows[idx].field}
onChange={(e) => handleGAVChange(idx, e)}
/>
</td>
<td>
<Input type="text"
name="gav_value" id="gav_value"
value={gavRows[idx].value}
onChange={(e) => handleGAVChange(idx, e)}
/>
</td>
<td>
<Button outline color="danger" onClick={() => handleGAVRemoveSpecificRow(idx)}><FaMinus /></Button>
</td>
</tr>)
})
}
</tbody>
</table>
你的问题是你使用数组的索引作为键。
阅读为什么不好:https://robinpokorny.medium.com/index-as-a-key-is-an-anti-pattern-e0349aece318
一个快速的 hack 是分配一个随机数作为 gavRows
中每个项目的键,并将其用作元素的键。查看更新后的代码:https://codesandbox.io/s/charming-bouman-03zn7
此外,元素的 id
在 DOM 中必须是唯一的,所以我从 input
元素中删除了它们。
问题是你输入了错误的值。
记住你设置的项目对象是:
const item = {
gav_field: "", //not field
gav_value: "" //not value
};
您应该修改来自
的代码
<td>
<Input
type="text"
name="gav_field"
id="gav_field"
value={gavRows[idx].field}
onChange={(e) => handleGAVChange(idx, e)}
/>
</td>
<td>
<Input
type="text"
name="gav_value"
id="gav_value"
value={gavRows[idx].value}
onChange={(e) => handleGAVChange(idx, e)}
/>
</td>
收件人:
<td>
<Input
type="text"
name="gav_field"
id="gav_field"
value={gavRows[idx].gav_field}
onChange={(e) => handleGAVChange(idx, e)}
/>
</td>
<td>
<Input
type="text"
name="gav_value"
id="gav_value"
value={gavRows[idx].gav_value}
onChange={(e) => handleGAVChange(idx, e)}
/>
</td>
这里用codesandbox模拟
https://codesandbox.io/embed/epic-nash-mxteu?fontsize=14&hidenavigation=1&theme=dark
当我从创建的动态行中删除一行时,我遇到了一个奇怪的行为。
我删除了带有 2 b 的行。如您所见,控制台日志具有正确的数据,而 UI 显示错误的数据。这意味着该功能运行良好但不知何故显示不正确。
有人知道为什么吗?提前致谢
截图
删除行之前
删除行后
源代码
const [gavRows, setGAVRows] = useState([]);
const handleGAVAddRow = async () => {
try {
const item = {
gav_field: '',
gav_value: ''
};
setGAVRows([...gavRows, item]);
} catch (error) {
console.log('error', error)
}
};
const handleGAVRemoveSpecificRow = (idx) => {
console.log('idx', idx)
const tempRows = [...gavRows];
console.log('tempRows', tempRows)
tempRows.splice(idx, 1);
setGAVRows(tempRows)
};
const handleGAVChange = async (idx, e) => {
const { name, value } = e.target;
var tempRows = [...gavRows];
tempRows[idx][name] = value;
setGAVRows(tempRows)
};
<table className="customgav_section">
<tbody>
{
gavRows.map((item, idx) => {
console.log('map idx', idx, item)
return (
<tr key={idx}>
<td>
<Input type="text"
name="gav_field" id="gav_field"
value={gavRows[idx].field}
onChange={(e) => handleGAVChange(idx, e)}
/>
</td>
<td>
<Input type="text"
name="gav_value" id="gav_value"
value={gavRows[idx].value}
onChange={(e) => handleGAVChange(idx, e)}
/>
</td>
<td>
<Button outline color="danger" onClick={() => handleGAVRemoveSpecificRow(idx)}><FaMinus /></Button>
</td>
</tr>)
})
}
</tbody>
</table>
你的问题是你使用数组的索引作为键。
阅读为什么不好:https://robinpokorny.medium.com/index-as-a-key-is-an-anti-pattern-e0349aece318
一个快速的 hack 是分配一个随机数作为 gavRows
中每个项目的键,并将其用作元素的键。查看更新后的代码:https://codesandbox.io/s/charming-bouman-03zn7
此外,元素的 id
在 DOM 中必须是唯一的,所以我从 input
元素中删除了它们。
问题是你输入了错误的值。
记住你设置的项目对象是:
const item = {
gav_field: "", //not field
gav_value: "" //not value
};
您应该修改来自
的代码<td>
<Input
type="text"
name="gav_field"
id="gav_field"
value={gavRows[idx].field}
onChange={(e) => handleGAVChange(idx, e)}
/>
</td>
<td>
<Input
type="text"
name="gav_value"
id="gav_value"
value={gavRows[idx].value}
onChange={(e) => handleGAVChange(idx, e)}
/>
</td>
收件人:
<td>
<Input
type="text"
name="gav_field"
id="gav_field"
value={gavRows[idx].gav_field}
onChange={(e) => handleGAVChange(idx, e)}
/>
</td>
<td>
<Input
type="text"
name="gav_value"
id="gav_value"
value={gavRows[idx].gav_value}
onChange={(e) => handleGAVChange(idx, e)}
/>
</td>