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

基于Material-UI与Formik的React可复用多选框表单组组件:数组对象Props传递及代码修正

修正后的可复用多选框表单组组件

没问题,你确实需要对facility数组做映射操作,这样才能渲染出所有的复选框选项。我帮你调整了组件代码,让它能接收选项数组作为props,同时修正了字段更新和验证逻辑,让组件更通用:

import { Checkbox, FormControl, FormControlLabel, FormGroup, FormLabel, FormHelperText } from '@material-ui/core';
import { useField, useFormikContext } from 'formik';

const CheckboxesGroup = ({ name, label, options, ...otherProps }) => {
  const { setFieldValue } = useFormikContext();
  const [field, meta] = useField(name);

  // 检查是否至少有一个选项被选中
  const hasSelectedOption = Object.values(field.value || {}).some(value => value);
  // 合并Formik字段错误与自定义选中验证错误
  const hasError = (meta.touched && meta.error) || !hasSelectedOption;

  // 处理单个复选框的切换事件
  const handleChange = (evt) => {
    const { name: optionName, checked } = evt.target;
    // 更新字段对象中对应选项的状态,保留其他选项的现有值
    setFieldValue(name, {
      ...field.value,
      [optionName]: checked
    });
  };

  const configFormControl = {
    error: hasError,
    component: "fieldset",
    sx: { m: 3 },
    variant: "standard",
    ...otherProps
  };

  return (
    <FormControl {...configFormControl}>
      <FormLabel component="legend">{label}</FormLabel>
      <FormGroup>
        {/* 遍历选项数组,动态生成每个复选框 */}
        {options.map((option) => (
          <FormControlLabel
            key={option.id}
            control={
              <Checkbox
                checked={field.value?.[option.name] || false}
                onChange={handleChange}
                name={option.name}
              />
            }
            label={option.label}
          />
        ))}
      </FormGroup>
      {/* 根据错误状态显示对应提示文本 */}
      <FormHelperText error={hasError}>
        {!hasSelectedOption ? 'Select at least one Slot' : meta.error}
      </FormHelperText>
    </FormControl>
  );
};

export default CheckboxesGroup;

在Form.js中使用该组件

现在你可以直接把facility数组作为options props传递给组件,记得在Formik表单的初始值里对应字段要设置为对象结构(比如timeSlots):

import CheckboxesGroup from './CheckboxesGroup';

// 修正了原数组里的两处笔误:时间范围错误、括号格式错误
const facility = [
  {id: 'morning_slot', name: 'morning_slot', label: 'Morning Slot [5AM-10AM]'},
  {id: 'afternoon_slot', name: 'afternoon_slot', label: 'Afternoon Slot [12PM-4PM]'},
  {id: 'evening_slot', name: 'evening_slot', label: 'Evening Slot [5PM-10PM]'}
];

// 在你的Formik表单组件内使用
<CheckboxesGroup
  name="timeSlots"
  label="Time-Slot"
  options={facility}
/>

关键修正说明

  1. 支持动态选项:通过接收options props,组件可以适配任意符合格式的复选框集合,复用性更强
  2. 正确维护多选状态:handleChange会更新字段对象中对应选项的值,而不是覆盖整个字段,保证多个复选框状态独立
  3. 优化验证逻辑:同时结合Formik的字段校验和自定义的"至少选一个"规则,错误状态判断更准确
  4. 动态错误提示:根据不同错误原因显示对应提示文本,提升用户体验

内容的提问来源于stack exchange,提问作者Rahul kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 14:42:43