React:取消复选框勾选后移除状态数组中的对应项
问题解决:复选框取消勾选时从useState数组中移除对应项
我已经实现了点击复选框时更新状态的功能,勾选时能成功把对应项添加到useState维护的addon数组里,但不清楚取消勾选时怎么从这个状态数组中移除对应的项。
现有代码
MainForm.jsx
const [addon, setAddon] = useState([]);
Addons.jsx
function AddOns({ addon, setAddon }) { const checkHandler = (e) => { if (e.target.checked === true) { setAddon([ ...addon, { value: e.target.value, checked: e.target.checked }, ]); } if (e.target.checked === false) { //I think filtering out an item here is the way to go? // setAddon((addon) => // addon.filter((e) => e.target.value !== e.target.value) //); } }; useEffect(() => { console.log(addon); }, [addon]); return( .... <Input value="Online service" dataAmount="+$1/mo" dataNumber="1" addonDetail="Access to multiplayer games" onClick={(e) => checkHandler(e)} /> ) }
解决方案
你想的没错,用filter确实能搞定移除,但原来的代码有两个小问题:
filter回调里的参数名和事件对象e重名了,导致根本拿不到正确的目标值- 取消勾选的逻辑可以优化,而且建议用函数式更新来获取最新状态,避免闭包导致的状态不一致问题
修改后的checkHandler代码如下:
const checkHandler = (e) => { const targetValue = e.target.value; if (e.target.checked) { // 先检查是否已经存在,别重复添加 const isAlreadyAdded = addon.some(item => item.value === targetValue); if (!isAlreadyAdded) { setAddon(prevAddons => [ ...prevAddons, { value: targetValue, checked: true } ]); } } else { // 过滤掉对应value的项,就是移除操作 setAddon(prevAddons => prevAddons.filter(item => item.value !== targetValue)); } };
几点关键说明:
- 先把
e.target.value存成targetValue,避免重复写,也防止变量名冲突 - 添加时用
some判断项是否已存在,不然勾一次加一次,数组里会有重复内容 - 不管添加还是移除,都用
prevAddons => ...这种函数式更新,确保每次操作的都是最新的状态,不会因为闭包拿旧状态 - 取消勾选时,
filter会留下所有value不等于目标值的项,相当于删掉了要取消的那个
另外,你的Input组件用的是onClick事件,其实复选框更适合用onChange,这样能更精准响应勾选状态的变化:
<Input value="Online service" dataAmount="+$1/mo" dataNumber="1" addonDetail="Access to multiplayer games" onChange={(e) => checkHandler(e)} />
内容的提问来源于stack exchange,提问作者Ninety9Balloons
相关产品推荐
相关产品推荐

