使用NativeBase自定义复选框实现全选功能的开发问题咨询
NativeBase 复选框全选功能实现
NativeBase的Checkbox组件onChange回调设计就是仅返回当前勾选状态的布尔值,不需要从事件对象中取源数据,React渲染列表时通过闭包传入当前项的标识即可完成逻辑绑定。你现有代码的核心问题是列表状态未设置更新方法、表单控件未做受控绑定,按以下逻辑修改即可:
- 把list状态改为可更新的写法,补充对应的setList方法,所有勾选状态变更都要同步回list数据源
- 全选框触发时直接拿回调返回的布尔值,批量更新所有列表项的checked属性,同时全量更新选中值数组
- 单个复选框的事件不需要通用绑定,在map渲染阶段用箭头函数闭包传入当前项的_id,拿到勾选状态后精准更新对应项即可
- Checkbox.Group必须绑定value属性关联groupValue状态,否则会出现视图和内部状态脱节的问题
修改后的可运行完整代码如下:
import { FC, useState } from 'react'; import { Box, Text, Checkbox, ICheckboxGroupProps } from 'native-base'; // 复选框列表项类型定义 type CheckListType = { _id: string; name: string; checked: boolean; }; const checkList: CheckListType[] = [ { _id: "one", name: "one", checked: false }, { _id: "two", name: "two", checked: false }, { _id: "three", name: "three", checked: false }, { _id: "four", name: "four", checked: false }, ]; export type CheckboxGroupProps = Omit< ICheckboxGroupProps, "size" | "colorScheme" >; const CheckBoxGroupTemplateEx: FC<CheckboxGroupProps> = () => { // 补充list的更新方法,用于同步每个选项的勾选状态 const [list, setList] = useState<CheckListType[]>(checkList); const [groupValue, setGroupValue] = useState<string[]>([]); const [selectedBoxes, setSelectedBoxes] = useState<string[]>([]); // 全选逻辑,入参是全选框返回的勾选布尔值 const handleSelectAllBoxes = (isAllSelected: boolean) => { setList(prev => prev.map(item => ({ ...item, checked: isAllSelected }))); const allSelectedValues = isAllSelected ? list.map(item => item.name) : []; setGroupValue(allSelectedValues); setSelectedBoxes(allSelectedValues); }; // 单个选项勾选逻辑,通过闭包传入当前项id const handleSelectBox = (isChecked: boolean, currentId: string) => { setList(prev => prev.map(item => item._id === currentId ? { ...item, checked: isChecked } : item )); const currentItemName = list.find(item => item._id === currentId)!.name; const newSelectedValues = isChecked ? [...selectedBoxes, currentItemName] : selectedBoxes.filter(name => name !== currentItemName); setSelectedBoxes(newSelectedValues); setGroupValue(newSelectedValues); }; return ( <Box alignItems="center" justifyContent="center"> <Text variant="bodyMd">{groupValue.length}</Text> <Checkbox value="select all" accessibilityLabel="select all" isChecked={selectedBoxes.length === list.length} onChange={handleSelectAllBoxes} > 全选 </Checkbox> {/* 给Group绑定value做受控组件 */} <Checkbox.Group value={groupValue} onChange={(values) => { setGroupValue(values || []); }} > {list.map(({ _id, name, checked }) => ( <Checkbox key={_id} m={2} value={name} accessibilityLabel={name} isChecked={checked} // 渲染时通过箭头函数传入当前项id,不需要从事件对象取数据 onChange={(isChecked) => handleSelectBox(isChecked, _id)} > {name} </Checkbox> ))} </Checkbox.Group> </Box> ); }; export default CheckBoxGroupTemplateEx;
补充说明:列表渲染时给外层Checkbox传key、通过闭包传参是React处理列表项事件的通用方案,不需要依赖组件回调返回原始数据对象,NativeBase的Checkbox没有返回完整事件对象是正常设计,不是功能缺陷。
内容的提问来源于stack exchange,提问作者nCat
相关产品推荐
相关产品推荐

