React勾选一个复选框以取消选中其他复选框



Hi我有一个父组件,它包含一堆子组件,这些子组件都是复选框。父组件内部是这样的:

const [items, setItems] = useState([
{
id:1,
selected: false,
},
{
id:2,
selected: false,
}
]);
const changeSelected = (id) =>
{
items.forEach((item)=>
{
if (item.id === id)
{
item.selected = !item.selected;
}
else{
item.selected = false;
}
})
}
return(
<div>
{items.map((item)=>{
<Child item={item} changeSelected={changeSelected}/>
})}
</div>
)

在子组件中,它内部有这样的东西:

return(
<div>
<input type="checkbox" checked={props.item.selected} onChange={()=>{props.changeSelected(props.item.id)}} />
</div>
)

我知道这部分不起作用是因为useState是异步的,但我不知道该怎么做才能让它起作用,或者我是否应该尝试不同的方法?谢谢

您可以将函数重构为:

const changeSelected = (id) => {
setItems(prev => ([...prev, {id, selected: !prev.filter(x => x.id === id)[0].selected}]))
}

很明显,我忘记了根据收到的两个答案设置Item。但我认为正确的方法是对我现有的items进行深入复制,然后再次设置Items。作为我未来的参考,以下是我现在正在做的工作(一个例子(:

let newItems = [...items];
newItems.forEach((item)=>
{
if (item.id === id)
{
item.selected = !item.selected;
}
else{
item.selected = false;
}
})
setProducts(newItems);

您不会在任何地方更新状态。您应该复制数组,然后更改您想要的对象:

const changeSelected = (id) =>
{ let newItems = [];
items.forEach((item)=>
{
if (item.id === id)
{
newItems.push({  id : item.id , selected : item.selected });
}
else{
newItems.push({  id : item.id , selected : false });
}
})
setItems(newItems);
}

调用setItems进行设置。

注意:与问题无关,但在遍历列表时应使用唯一键。

{items.map((item)=>{
<Child key={item.id} item={item} changeSelected={changeSelected}/>
})}

最新更新