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

React页面加载时仅勾选最后一组复选框问题求助

多组复选框仅最后一组默认选中的修复方案

问题描述

我有两组独立复选框,每组对应专属字段,部分复选框需要在页面加载时默认选中。但目前只有最后一组的复选框能被默认勾选,第一组完全失效;移除第二组后功能恢复正常,添加后问题重现。

原代码

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import { Checkbox, Pane, Label } from "evergreen-ui";

function ControlledCheckboxExample() {
  const [checked, setChecked] = React.useState(true);
  const [fieldchecked, setIsFieldChecked] = React.useState(false);
  const [editContactFields, setContactFields] = React.useState([]);
  useEffect(() => {
    loaddata();
  }, []);
  const loaddata = () => {
    let data = [
      {
        id: 1,
        label: "First Checkbox",
        type: "checkbox",
        selectedvalue: [
          {
            value: "one"
          },
          {
            value: "two"
          }
        ],
        hasvalue: true,
        tag: "UNIQUEONE",
        options: [
          {
            value: "one",
            text: "one"
          },
          {
            value: "two",
            text: "two"
          },
          {
            value: "three",
            text: "three"
          },
          {
            value: "four",
            text: "four"
          }
        ],
        visible: true
      },
      {
        id: 2,
        label: "Second Checkbox",
        type: "checkbox",
        selectedvalue: [
          {
            value: "five"
          }
        ],
        hasvalue: true,
        tag: "UNIQUETWO",
        options: [
          {
            value: "five",
            text: "five"
          }
        ],
        visible: true
      }
    ];
    setContactFields(data);
    data.map((field, index) => {
      if (field.type === "checkbox" && field.hasvalue == true) {
        setIsFieldChecked(false);
        let value = field.selectedvalue;
        let tag = field.tag;
        value.map((realvalue) => {
          let fieldvalud = realvalue.value;
          setIsFieldChecked((fieldchecked) => ({
            ...fieldchecked,
            [fieldvalud + tag]: !fieldchecked[fieldvalud + tag]
          }));
        });
      }
    });
  };

  const handlefieldchecked = (a, f) => {
    const fieldvalud = a;
    const tag = f;

    setIsFieldChecked((fieldchecked) => ({
      ...fieldchecked,
      [fieldvalud + tag]: !fieldchecked[fieldvalud + tag]
    }));
  };

  return (
    <Pane>
      {editContactFields.map((field) => (
        <Pane>
          <Label>
            {field.label} {field.required == true && "*"}
          </Label>
          {field.options.map((checkboxfield) => (
            <Checkbox
              name={field.tag + "[]"}
              id={field.tag}
              type={field.type}
              value={checkboxfield.value}
              label={checkboxfield.text}
              checked={fieldchecked[checkboxfield.value + field.tag]}
              required={field.required}
              onChange={(e) =>
                handlefieldchecked(checkboxfield.value, field.tag)
              }
            />
          ))}
        </Pane>
      ))}
    </Pane>
  );
}

ReactDOM.render(<ControlledCheckboxExample />, document.getElementById("root"));

问题分析

  1. 初始状态错误:fieldchecked初始化为false,但它需要存储键值对形式的选中状态映射,应该是一个空对象{}。
  2. 状态重置覆盖:遍历每组字段时调用setIsFieldChecked(false),会清空之前设置的第一组选中状态,导致只有最后一组的设置保留。
  3. 批量更新冲突:React会批量处理多次setState调用,前面的更新会被后面的重置操作覆盖,最终只保留最后一组的选中状态。

修复方案

步骤1:修正初始状态

将fieldchecked的初始值改为空对象:

const [fieldchecked, setIsFieldChecked] = React.useState({});

步骤2:移除状态重置操作

删除loaddata中遍历字段时的setIsFieldChecked(false),避免清空已设置的状态。

步骤3:构建完整选中状态后一次性更新

预先遍历所有数据,构建好完整的选中状态对象,再一次性调用setState,避免多次更新的冲突:

const loaddata = () => {
  let data = [/* 原数据 */];
  setContactFields(data);
  
  // 预先构建选中状态对象
  const initialChecked = {};
  data.forEach((field) => {
    if (field.type === "checkbox" && field.hasvalue) {
      field.selectedvalue.forEach((realvalue) => {
        const key = `${realvalue.value}${field.tag}`;
        initialChecked[key] = true;
      });
    }
  });
  setIsFieldChecked(initialChecked);
};

修复后的完整代码

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import { Checkbox, Pane, Label } from "evergreen-ui";

function ControlledCheckboxExample() {
  const [checked, setChecked] = React.useState(true);
  // 修正初始状态为对象
  const [fieldchecked, setIsFieldChecked] = React.useState({});
  const [editContactFields, setContactFields] = React.useState([]);
  
  useEffect(() => {
    loaddata();
  }, []);
  
  const loaddata = () => {
    let data = [
      {
        id: 1,
        label: "First Checkbox",
        type: "checkbox",
        selectedvalue: [
          { value: "one" },
          { value: "two" }
        ],
        hasvalue: true,
        tag: "UNIQUEONE",
        options: [
          { value: "one", text: "one" },
          { value: "two", text: "two" },
          { value: "three", text: "three" },
          { value: "four", text: "four" }
        ],
        visible: true
      },
      {
        id: 2,
        label: "Second Checkbox",
        type: "checkbox",
        selectedvalue: [
          { value: "five" }
        ],
        hasvalue: true,
        tag: "UNIQUETWO",
        options: [
          { value: "five", text: "five" }
        ],
        visible: true
      }
    ];
    setContactFields(data);
    
    // 一次性构建初始选中状态
    const initialChecked = {};
    data.forEach(field => {
      if (field.type === "checkbox" && field.hasvalue) {
        field.selectedvalue.forEach(realvalue => {
          const key = `${realvalue.value}${field.tag}`;
          initialChecked[key] = true;
        });
      }
    });
    setIsFieldChecked(initialChecked);
  };

  const handlefieldchecked = (a, f) => {
    const fieldvalud = a;
    const tag = f;

    setIsFieldChecked((fieldchecked) => ({
      ...fieldchecked,
      [fieldvalud + tag]: !fieldchecked[fieldvalud + tag]
    }));
  };

  return (
    <Pane>
      {editContactFields.map((field) => (
        {/* 添加key避免React渲染警告 */}
        <Pane key={field.id}>
          <Label>
            {field.label} {field.required == true && "*"}
          </Label>
          {field.options.map((checkboxfield) => (
            {/* 添加唯一key */}
            <Checkbox
              key={`${field.tag}-${checkboxfield.value}`}
              name={field.tag + "[]"}
              id={`${field.tag}-${checkboxfield.value}`}
              type={field.type}
              value={checkboxfield.value}
              label={checkboxfield.text}
              checked={fieldchecked[checkboxfield.value + field.tag]}
              required={field.required}
              onChange={(e) =>
                handlefieldchecked(checkboxfield.value, field.tag)
              }
            />
          ))}
        </Pane>
      ))}
    </Pane>
  );
}

ReactDOM.render(<ControlledCheckboxExample />, document.getElementById("root"));

额外优化:给map循环的元素添加了唯一key,避免React渲染警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 07:30:53