React使用复选框+useState过滤数组时复选框无法保持选中如何解决?
问题根因
- 核心原因:你将
EmittersCheckboxes组件定义在了父组件内部。点击复选框更新父组件的searchUser状态后,父组件会触发重渲染,此时内部定义的EmittersCheckboxes会被判定为全新的组件实例,旧实例直接卸载、新实例重新挂载,它内部的checkedState会被重置为初始的全false数组,因此复选框无法保持选中状态。 - 冗余设计问题:你同时维护了父组件
searchUser、子组件checkedState两套状态控制选中逻辑,两套状态不同步也会导致选中状态异常,完全没有必要维护重复的状态。
解决方案
- 将
EmittersCheckboxes组件移到父组件外部定义,避免父组件重渲染时子组件被销毁重建,组件需要用到的数据通过props传入即可。 - 删除子组件内部的
checkedState状态,直接用传入的searchUser判断复选框是否选中,统一用一套状态控制逻辑。
修改后的子组件代码
// 移到父组件外部定义,所需数据通过props传入 interface EmittersCheckboxesProps { emittersData: any[]; searchUser: string[]; setSearchUser: React.Dispatch<React.SetStateAction<string[]>>; } function EmittersCheckboxes ({ emittersData, searchUser, setSearchUser }: EmittersCheckboxesProps) { const handleOnChange = (label: string) => { setSearchUser((prev) => prev.includes(label) ? prev.filter((item) => item !== label) : [...prev, label] ) }; return ( <div className="App"> {emittersData.map((value: any, index: number) => { const label = value.Attributes[2].Value; return ( <li key={index}> <div className="toppings-list-item"> <div className="left-section"> <input className="h-4 w-4 focus:bg-indigo border-2 border-gray-300 rounded" type="checkbox" id={`custom-checkbox-${index}`} name={label} value={label} // 直接用searchUser判断选中状态,无需内部状态 checked={searchUser.includes(label)} onChange={() => handleOnChange(label)} /> <label className="ml-3 font-medium text-sm text-gray-700 dark:text-primary" htmlFor={`custom-checkbox-${index}`}>{label}</label> </div> </div> </li> ); })} </div> ) }
父组件调用代码
// 父组件内渲染时传入对应的props即可 <ul> <EmittersCheckboxes emittersData={emittersData} searchUser={searchUser} setSearchUser={setSearchUser} /> </ul>
内容的提问来源于stack exchange,提问作者Henrique Monteiro
相关产品推荐
相关产品推荐

