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

React表单中统计Yes/No答案并存入数组的实现方法

实现选中Yes时向数组添加元素的方案

从你的代码来看,你应该是用react-hook-form处理表单逻辑(用到了register方法),下面分步骤实现需求:

1. 初始化状态数组

首先在组件顶部用React的useState钩子初始化questionAns数组,用来存储选中的"Yes"回答:

import { useState } from 'react';
// ... 其他Material UI和react-hook-form的导入

export default function YourFormComponent() {
  // 初始化空数组存储Yes回答
  const [questionAns, setQuestionAns] = useState([]);
  // 初始化react-hook-form(如果还没写的话)
  const { register, errors, watch } = useForm();
  
  // ... 其他逻辑和渲染代码
}

2. 监听单选框选择并更新数组

有两种简单的方式实现监听,选一种适合你的即可:

方式一:给RadioGroup绑定onChange事件

直接给RadioGroup添加回调函数,当选中值变化时判断是否为"Yes",再更新数组:

<FormControl error={Boolean(errors.question1)}>
  <FormLabel component="legend">
    {Records[0].question}
  </FormLabel>
  <RadioGroup 
    row 
    aria-label="question1" 
    name="question1"
    onChange={(e) => {
      const selectedValue = e.target.value;
      if (selectedValue === "Yes") {
        // 注意:必须创建新数组,不能直接修改原数组
        setQuestionAns(prev => [...prev, 'yes']);
      } else {
        // 可选:如果需要取消选择Yes时移除对应元素,可添加以下代码
        // setQuestionAns(prev => prev.filter(item => item !== 'yes'));
      }
    }}
  >
    <FormControlLabel
      value="Yes"
      control={
        <Radio
          {...register("awQuestion1", {
            required: "Please select a response.",
          })}
        />
      }
      label="Yes"
    />
    <FormControlLabel
      value="No"
      control={
        <Radio
          {...register("awQuestion1", {
            required: "Please select a response.",
          })}
        />
      }
      label="No"
    />
  </RadioGroup>
  <FormHelperText style={{ color: "#d32f2f" }}>
    {errors.question1?.message}
  </FormHelperText>
</FormControl>

方式二:用react-hook-form的watch监听字段变化

通过watch函数监听单选框字段的变化,结合useEffect处理数组更新:

import { useEffect } from 'react';
import { useForm, watch } from 'react-hook-form';

export default function YourFormComponent() {
  const [questionAns, setQuestionAns] = useState([]);
  const { register, errors } = useForm();
  // 监听awQuestion1字段的实时值
  const selectedValue = watch('awQuestion1');

  // 当选中值变化时触发逻辑
  useEffect(() => {
    if (selectedValue === "Yes") {
      setQuestionAns(prev => [...prev, 'yes']);
    } else {
      // 可选:取消选择Yes时移除对应元素
      // setQuestionAns(prev => prev.filter(item => item !== 'yes'));
    }
  }, [selectedValue]); // 依赖选中值,值变化时执行

  // ... 渲染表单的代码
}

3. 处理多个结构相同的问题

如果有大量相同结构的Yes/No问题,最好封装成可复用组件,避免重复代码:

第一步:创建复用的YesNoQuestion组件

// YesNoQuestion.jsx
import React from 'react';
import { FormControl, FormLabel, RadioGroup, FormControlLabel, Radio, FormHelperText } from '@mui/material';
import { useFormContext } from 'react-hook-form';

export default function YesNoQuestion({ questionText, fieldKey, error, onYesSelect }) {
  const { register } = useFormContext(); // 借助FormContext共享表单方法

  return (
    <FormControl error={Boolean(error)}>
      <FormLabel component="legend">{questionText}</FormLabel>
      <RadioGroup 
        row 
        aria-label={fieldKey} 
        name={fieldKey}
        onChange={(e) => {
          if (e.target.value === "Yes") {
            onYesSelect(); // 触发父组件的数组更新逻辑
          }
        }}
      >
        <FormControlLabel
          value="Yes"
          control={<Radio {...register(fieldKey, { required: "Please select a response." })} />}
          label="Yes"
        />
        <FormControlLabel
          value="No"
          control={<Radio {...register(fieldKey, { required: "Please select a response." })} />}
          label="No"
        />
      </RadioGroup>
      <FormHelperText style={{ color: "#d32f2f" }}>
        {error?.message}
      </FormHelperText>
    </FormControl>
  );
}

第二步:在父组件中批量使用该组件

// 父组件
import YesNoQuestion from './YesNoQuestion';
import { useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';

export default function YourForm() {
  const [questionAns, setQuestionAns] = useState([]);
  const methods = useForm();
  const { errors } = methods;

  const handleYesSelect = () => {
    setQuestionAns(prev => [...prev, 'yes']);
  };

  return (
    <FormProvider {...methods}>
      {/* 第一个问题 */}
      <YesNoQuestion 
        questionText={Records[0].question}
        fieldKey="awQuestion1"
        error={errors.awQuestion1}
        onYesSelect={handleYesSelect}
      />
      {/* 第二个问题 */}
      <YesNoQuestion 
        questionText={Records[1].question}
        fieldKey="awQuestion2"
        error={errors.awQuestion2}
        onYesSelect={handleYesSelect}
      />
      {/* 更多问题直接复制上述代码,修改对应参数即可 */}
    </FormProvider>
  );
}

额外提示

如果需要区分是哪个问题的Yes回答,可以修改handleYesSelect,传递问题标识,比如往数组中存入{questionId: 1, answer: 'yes'}这类对象,方便后续对具体问题的回答做处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 11:31:01