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

如何用Yup验证name为choices[]的多选复选框(React+Formik)

解决方案:直接用Yup验证choices[]复选框组至少选一个

我明白你现在的痛点——用隐藏字段绕一圈确实有点冗余,其实Formik+Yup完全可以直接处理choices[]这种数组类型的复选框验证,不用额外的状态管理。问题出在你之前的Yup规则用错了类型:choices[]在Formik里会被处理成数组(选中的复选框值的集合),而不是单个布尔值,所以我们需要针对数组来写验证规则。

步骤1:修正Yup验证规则

把原来针对隐藏字段的规则替换成针对choices[]的数组验证:

import * as Yup from 'yup';

const validationSchema = Yup.object().shape({
  'choices[]': Yup.array()
    .of(Yup.string()) // 匹配复选框的value类型(你的例子里是字符串)
    .min(1, '请至少选择一个选项') // 核心规则:数组长度至少为1
    .required('请至少选择一个选项') // 确保字段存在(可选,根据你的需求调整)
});

步骤2:简化CheckboxGroupChoices组件

你不需要再维护checkedCounter状态和隐藏字段了,Formik会自动收集choices[]的选中值为数组。修改后的组件可以去掉多余的状态、useEffect和validateCheckboxRequired函数,直接让Formik处理值的更新:

import React from 'react'
import Checkbox from ...
import CheckboxProps from ...
import CheckboxGroup from ...
import Label from ...
import { useFormikContext } from 'formik'; // 引入Formik的上下文钩子

export interface CheckboxGroupChoicesProps {}

const CheckboxGroupChoices: React.FunctionComponent<CheckboxGroupChoicesProps> = () => {
  // 获取Formik的handleChange方法,用来处理复选框的变化
  const { handleChange, values } = useFormikContext();

  const getCheckboxes = () => {
    const options = ['Car', 'Van', 'Bike'];
    return options.map((option, key) => (
      <Checkbox
        label={option}
        value={option}
        disabled={false}
        name={'choices[]'}
        key={`choices-${key}`}
        handleOnClick={handleChange} // 直接用Formik的handleChange
        checked={values['choices[]']?.includes(option)} // 同步选中状态
      />
    ));
  };

  return (
    <>
      <Label>Pick choices</Label>
      <CheckboxGroup columns={3}>{getCheckboxes()}</CheckboxGroup>
    </>
  );
};

export default CheckboxGroupChoices;

为什么这个方案可行?

  • Formik会自动识别name为choices[]的表单控件,将所有选中的复选框值收集成一个数组(比如选中Car和Van的话,form.values['choices[]']就是['Car', 'Van'],没选的话是undefined或者空数组)。
  • Yup的array().min(1)规则会直接验证这个数组的长度,确保至少有一个元素,完美满足“至少选一个”的需求。

补充:初始值设置

如果你在Formik的initialValues里没有给choices[]设置初始值,建议加上空数组,避免undefined导致的验证问题:

const initialValues = {
  // 其他字段...
  'choices[]': []
};

这样整个流程就完全不需要隐藏字段和额外的状态管理了,代码更简洁,逻辑也更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:34:14