复选框未取消选中 React
Checkbox not unchecking with React
我有一组匹配项,在我的 React 应用程序中显示为行列表。每行有两名运动员,您可以使用复选框来预测哪一个会获胜。每行只能检查一名运动员,所以我做了类似以下的操作来存储谁被检查,谁没有:
在初始安装时,我有一个空的 object 处于名为 predictions
的状态。当用户开始与复选框交互时,我使用每行的索引作为键来存储其中一名运动员的 ID。这就是它在实践中的样子,
{
0: '12864',
3: '13333',
5: '45362',
...etc
}
所以你可以更好地了解我在做什么,这是一个屏幕截图。
在我的 React 代码中,我通过匹配数组进行映射,如下所示:
<ul>
{matches &&
matches.map((match, i) => (
<li
key={match.fighter_a_name + match.fighter_b_name}
className="text-center"
>
<Row>
<Col md={5}>
<h3>
{match.fighter_a_name}
</h3>
<FormCheck
type="checkbox"
id={match.fighter_a_id}
idx={i}
onChange={handlePrediction}
checked={
parseInt(predictions[i]) === match.fighter_a_id ||
false
}
/>
</Col>
<Col md={2}>
{/* <div>{match.weight}</div>
<div>{match.result}</div>
<div>{match.time}</div> */}
<div>{match.rounds}</div>
</Col>
<Col md={5}>
<h3>
{match.fighter_b_name}
</h3>
<FormCheck
id={match.fighter_b_id}
idx={i}
onChange={handlePrediction}
checked={
parseInt(predictions[i]) === match.fighter_b_id ||
false
}
/>
</Col>
</Row>
</li>
))}
</ul>
每次单击复选框都会执行名为 handlePrediction
的函数,该函数处理更新预测的逻辑 object。它主要检查它们当前是否是 object 中的键,其 id 值与刚刚单击的复选框相同。如果是这样,它将从 object 中删除该键,否则,它只是将该键添加到 object,或覆盖该键的当前 ID。
我想我这里可能有一些逻辑问题,但现在,就是这样了。
const handlePrediction = (e) => {
const id = e.target.id;
const idx = e.target.getAttribute("idx");
if (predictions[idx] === id) {
setPredictions((prev) => {
delete prev[idx];
return prev;
});
} else {
setPredictions((prev) => ({ ...prev, [idx]: id }));
}
};
既然我给了你背景故事,我遇到的问题是我无法取消选中特定场景中的运动员。如果我检查一行中的运动员,他们的 id 将成功添加到 object。然后,如果我勾选同一行的另一个运动员,前一个运动员变成未勾选,而刚刚点击的运动员变成勾选,这就是我想要的。
但是,如果我选中一名运动员,然后尝试取消选中他们,则该复选框会永久保持选中状态。每次单击时,handlePrediction
函数似乎都能正确处理所有内容,adds/removes 来自 object 的用户,但复选框没有任何变化。
我不知道为什么复选框不会取消选中。我创建了一个 slimmed down version of this code in a Codepen,您可以对其进行修改,它具有完整的匹配数据数组,因此您也可以看到它的样子。
P.S.
我还发现了其他问题。如果您使用代码笔,请执行以下操作:
- 检查肖恩·斯特里克兰
- 检查 Cheyanne Buys
- 检查肖恩·斯特里克兰
- 检查 Cheyanne Buys
- 检查肖恩·斯特里克兰
在第 5 步之后,您应该会看到 Cheyanne Buys 未被选中,这是不应该发生的。我这里肯定做错了什么。
因为你改变了原始状态,所以即使你设置状态,看起来你也为当前状态设置了相同的值
您可以尝试克隆原始对象,并改变复制对象和return它
代码如下:
const handlePrediction = (e) => {
const id = e.target.id;
const idx = e.target.getAttribute("idx");
if (predictions[idx] === id) {
setPredictions((prev) => {
// clone a new object
const newPrediction = { ...prev };
delete newPrediction [idx];
return newPrediction;
});
} else {
setPredictions((prev) => ({ ...prev, [idx]: id }));
}
};
我有一组匹配项,在我的 React 应用程序中显示为行列表。每行有两名运动员,您可以使用复选框来预测哪一个会获胜。每行只能检查一名运动员,所以我做了类似以下的操作来存储谁被检查,谁没有:
在初始安装时,我有一个空的 object 处于名为 predictions
的状态。当用户开始与复选框交互时,我使用每行的索引作为键来存储其中一名运动员的 ID。这就是它在实践中的样子,
{
0: '12864',
3: '13333',
5: '45362',
...etc
}
所以你可以更好地了解我在做什么,这是一个屏幕截图。
在我的 React 代码中,我通过匹配数组进行映射,如下所示:
<ul>
{matches &&
matches.map((match, i) => (
<li
key={match.fighter_a_name + match.fighter_b_name}
className="text-center"
>
<Row>
<Col md={5}>
<h3>
{match.fighter_a_name}
</h3>
<FormCheck
type="checkbox"
id={match.fighter_a_id}
idx={i}
onChange={handlePrediction}
checked={
parseInt(predictions[i]) === match.fighter_a_id ||
false
}
/>
</Col>
<Col md={2}>
{/* <div>{match.weight}</div>
<div>{match.result}</div>
<div>{match.time}</div> */}
<div>{match.rounds}</div>
</Col>
<Col md={5}>
<h3>
{match.fighter_b_name}
</h3>
<FormCheck
id={match.fighter_b_id}
idx={i}
onChange={handlePrediction}
checked={
parseInt(predictions[i]) === match.fighter_b_id ||
false
}
/>
</Col>
</Row>
</li>
))}
</ul>
每次单击复选框都会执行名为 handlePrediction
的函数,该函数处理更新预测的逻辑 object。它主要检查它们当前是否是 object 中的键,其 id 值与刚刚单击的复选框相同。如果是这样,它将从 object 中删除该键,否则,它只是将该键添加到 object,或覆盖该键的当前 ID。
我想我这里可能有一些逻辑问题,但现在,就是这样了。
const handlePrediction = (e) => {
const id = e.target.id;
const idx = e.target.getAttribute("idx");
if (predictions[idx] === id) {
setPredictions((prev) => {
delete prev[idx];
return prev;
});
} else {
setPredictions((prev) => ({ ...prev, [idx]: id }));
}
};
既然我给了你背景故事,我遇到的问题是我无法取消选中特定场景中的运动员。如果我检查一行中的运动员,他们的 id 将成功添加到 object。然后,如果我勾选同一行的另一个运动员,前一个运动员变成未勾选,而刚刚点击的运动员变成勾选,这就是我想要的。
但是,如果我选中一名运动员,然后尝试取消选中他们,则该复选框会永久保持选中状态。每次单击时,handlePrediction
函数似乎都能正确处理所有内容,adds/removes 来自 object 的用户,但复选框没有任何变化。
我不知道为什么复选框不会取消选中。我创建了一个 slimmed down version of this code in a Codepen,您可以对其进行修改,它具有完整的匹配数据数组,因此您也可以看到它的样子。
P.S. 我还发现了其他问题。如果您使用代码笔,请执行以下操作:
- 检查肖恩·斯特里克兰
- 检查 Cheyanne Buys
- 检查肖恩·斯特里克兰
- 检查 Cheyanne Buys
- 检查肖恩·斯特里克兰
在第 5 步之后,您应该会看到 Cheyanne Buys 未被选中,这是不应该发生的。我这里肯定做错了什么。
因为你改变了原始状态,所以即使你设置状态,看起来你也为当前状态设置了相同的值
您可以尝试克隆原始对象,并改变复制对象和return它
代码如下:
const handlePrediction = (e) => {
const id = e.target.id;
const idx = e.target.getAttribute("idx");
if (predictions[idx] === id) {
setPredictions((prev) => {
// clone a new object
const newPrediction = { ...prev };
delete newPrediction [idx];
return newPrediction;
});
} else {
setPredictions((prev) => ({ ...prev, [idx]: id }));
}
};