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;

 

posted @ 2023-01-04 15:40  王希有  阅读(1377)  评论(0编辑  收藏  举报