react中antd使用Checkbox通过返回的数据结构实现分类多选
"react": "^18.2.0",
"antd": "^5.1.1",
先看效果(不选和多选)
// 假设后端返回数据结构
const data = {
fruit: [
{ label: 'Apple', value: 'apple' },
{ label: 'Pear', value: 'pear' },
{ label: 'Orange', value: 'orange' },
],
animal: [
{ label: 'Cat', value: 'cat' },
{ label: 'Dog', value: 'dog' },
{ label: 'Horse', value: 'horse' },
],
cat: [
{ label: 'Honda', value: 'honda' },
{ label: 'Ben', value: 'ben' },
{ label: 'Da', value: 'Da' },
]
}
完整 inde.tsx
// react中antd使用Checkbox实现分类多选 import React, { useEffect, useState } from 'react'; import { Button, Checkbox, Divider } from 'antd'; import type { CheckboxChangeEvent } from 'antd/es/checkbox'; import type { CheckboxOptionType, CheckboxValueType } from 'antd/es/checkbox/Group'; const CheckboxGroup = Checkbox.Group; const AddList = () => { const [groupNames, setGroupNames] = useState<string[]>([]); const [options, setOptions] = useState<CheckboxOptionType[][]>([]); const [indeterminates, setIndeterminates] = useState<{[key: string]: boolean}>({}); const [checkAlls, setCheckAlls] = useState<{[key: string]: boolean}>({}); const [checkedLists, setCheckedLists] = useState<{[key: string]: CheckboxValueType[]}>({}); useEffect(() => { setTimeout(() => { // 假设后端返回数据结构 const data = { fruit: [ { label: 'Apple', value: 'apple' }, { label: 'Pear', value: 'pear' }, { label: 'Orange', value: 'orange' }, ], animal: [ { label: 'Cat', value: 'cat' }, { label: 'Dog', value: 'dog' }, { label: 'Horse', value: 'horse' }, ], cat: [ { label: 'Honda', value: 'honda' }, { label: 'Ben', value: 'ben' }, { label: 'Da', value: 'Da' }, ] } // 将keys 和 values 分开存储 setGroupNames(Object.keys(data)) setOptions(Object.values(data)) // 当个单选及全选样式修改 const keys = Object.keys(data) const ins = {} as any keys.map(item => ins[item] = false) setIndeterminates(ins) setCheckAlls(ins) }, 500); // // 测试异步赋值, 已测,可实现 // setTimeout(() => { // setCheckedLists({...checkedLists, fruit: ['apple', 'orange'], animal: ['dog']}) // }, 1000); }, []) const onChange = (item: string, i: number, list: CheckboxValueType[]) => { const plainOptions = options[i].map(item => item.value) setCheckedLists({...checkedLists, [item]: list}); setIndeterminates({ ...indeterminates, [item]: !!list.length && list.length < plainOptions.length }); setCheckAlls({ ...checkAlls, [item]: list.length === plainOptions.length }); }; const onCheckAllChange = (item: string, i:number, e: CheckboxChangeEvent) => { const plainOptions = options[i].map(item => item.value) setCheckedLists({ ...checkedLists, [item]: e.target.checked ? plainOptions : []}); setIndeterminates({ ...indeterminates, [item]: false }); setCheckAlls({ ...checkAlls, [item]: e.target.checked }); }; const checkGroup = groupNames.map((item, index) => { return ( <div key={index}> <Checkbox indeterminate={indeterminates[item]} onChange={(e) => onCheckAllChange(item, index, e)} checked={checkAlls[item]}>{item}</Checkbox> <br/> <CheckboxGroup options={options[index]} value={checkedLists[item]} onChange={(list) => onChange(item, index, list)} /> <Divider /> </div> ) }) return ( <> {checkGroup} <div> 选中数据:{JSON.stringify(checkedLists)} </div> </> ) } export default AddList;