You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Material-UI React实现带全选/取消全选的复选框多选组件

解决多选组件全选/取消全选标签切换问题

你只需利用已有的isAllSelected状态变量,动态切换ListItemText的文本内容即可,同时还能顺便修正几处潜在问题:

修改后的核心代码

import React from 'react'
import { Checkbox, InputLabel, ListItemIcon, ListItemText, MenuItem, FormControl, Select } from '@material-ui/core'
import { MenuProps, useStyles } from './multiSelectWithCheckboxUtil'


function MultiSelectWithCheckbox(props) {
    const classes = useStyles()
    const isAllSelected = props.options.length > 0 && props.value.length === props.options.length

    const handleChange = React.useCallback(event => {
        const value = event.target.value
        if (value[value.length - 1] === 'all') {
            props.onChange(props.value.length === props.options.length ? [] : props.options)
            return
        }
        props.onChange(value)
    }, [ props.value, props.options ]) // 补充依赖项,避免闭包问题

    return (
        <FormControl className={classes.formControl}>
            <InputLabel id='mutiple-select-label' style={{fontSize: 18}}>{props.label}</InputLabel>
            <Select
                labelId='mutiple-select-label'
                multiple
                value={props.value}
                onChange={handleChange}
                renderValue={React.useCallback(selected => selected.join(', '))}
                MenuProps={MenuProps}
            >
                <MenuItem
                    value='all'
                    classes={{
                        root: isAllSelected ? classes.selectedAll : '',
                    }}
                >
                    <ListItemIcon>
                        <Checkbox
                            classes={{
                                indeterminate: classes.indeterminateColor,
                            }}
                            checked={isAllSelected}
                            indeterminate={props.value.length > 0 && props.value.length < props.options.length} // 修正数组长度判断
                        />
                    </ListItemIcon>
                    <ListItemText
                        classes={{ primary: classes.selectAllText }}
                        primary={isAllSelected ? '取消全选' : '全选'} // 核心:根据状态切换文本
                    />
                </MenuItem>
                {props.options.map(option => (
                    <MenuItem key={option} value={option}>
                        <ListItemIcon>
                            <Checkbox checked={props.value.indexOf(option) > -1} />
                        </ListItemIcon>
                        <ListItemText primary={option} />
                    </MenuItem>
                ))}
            </Select>
        </FormControl>
    )
}

export default MultiSelectWithCheckbox

关键调整说明

  1. 标签文本动态切换:通过isAllSelected状态判断,全选时显示“取消全选”,未全选时显示“全选”
  2. 修复闭包问题:给handleChange补充props.options依赖项,避免选项更新后逻辑失效
  3. 修正半选状态判断:原代码中props.value > 0错误,改为props.value.length > 0(因为props.value是数组)

内容的提问来源于stack exchange,提问作者KARTHIKEYAN.A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 05:00:32