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

如何使用Formik实现一组复选框点击时独立修改UI状态

问题修复方案

问题根因

你当前的代码之所以表现得像单选按钮,是存在两个核心错误:

  • 选中状态更新逻辑错误:handleSetChecked方法每次执行时都会先生成全为false的新状态数组,仅把当前点击项设为true,相当于每次点击都会自动清空其他所有项的选中状态
  • 复选框checked属性硬编码:Field组件的checked属性固定写为true,没有和你维护的checkedStatus状态绑定,原生控件状态和业务状态完全脱节

修复后代码

import { useState } from 'react'

function RecordGame() {
  const [checkedStatus, setCheckedStatus] = useState(members.map(() => false))

  const handleSetChecked = (index) => {
    // 基于原有状态拷贝数组,不会影响其他项的选中状态
    const newState = [...checkedStatus]
    // 仅翻转当前点击项的选中状态
    newState[index] = !newState[index]
    setCheckedStatus(newState)
  }

  const playerCheckboxes = members.map((player, index) => {
    return (
      <div key={index} className="flex gap-2">
        <label htmlFor={player.name}>
          <Field
            // 绑定对应项的选中状态,不要硬编码
            checked={checkedStatus[index]}
            type="checkbox"
            onClick={() => handleSetChecked(index)}
            id={player.name}
            name="players"
            value={player.name}
          />
          <span
            className={`${checkedStatus[index] ? 'bg-quad text-primary' : 'bg-transparent'}`}
          >
            {player.name}
          </span>
        </label>
      </div>
    )
  })

  // 修正JSX返回语法,用Fragment包裹列表
  return <>{playerCheckboxes}</>
}

关键修改说明

  • 调整状态更新逻辑:不再每次重置所有项的选中状态,仅翻转当前点击项的状态,实现多选项独立控制
  • 绑定复选框选中属性:将Field的checked属性和checkedStatus[index]绑定,保证控件显示和业务状态一致
  • 移除不必要的async修饰符:当前逻辑无异步操作,不需要异步声明
  • 修正返回值语法错误:原返回写法不符合JSX规范,补充React Fragment包裹元素列表

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 01:12:00