如何在 Formik 中使用多组单选按钮

How to work with multiple groups of radio buttons in Formik

我有这个组件,它基本上遍历一系列问题,每个问题都有选择和 onSubmit,我想捕获问题的索引以及用户选择的答案。从服务器检索问题列表后,我生成了一个包含对象的数组,每个对象都有一个 quesitonanswer 属性,然后使用它来初始化表单。我的实现类似于下面...

import React from "react";
import { Formik } from "formik";

const questions = [
  {
    question: "What is 1 + 1?",
    choices: [
      { option: "A", answer: 2 },
      { option: "B", answer: 3 },
      { option: "C", answer: 4 },
      { option: "D", answer: 8 },
    ],
  },
    {
    question: "What is 3 * 3?",
    choices: [
      { option: "A", answer: 2 },
      { option: "B", answer: 3 },
      { option: "C", answer: 4 },
      { option: "D", answer: 8 },
    ],
  },
];

class Questions extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      questions: [],
    };
  }

  userSelection(length) {
    const initialValues = [];
    for (let i = 0; i < length; i++) {
      initialValues.push({ question: i, answer: "" });
    }

    return initialValues;
  }

  componentDidMount() {
    // Fetch all the questions and set state
    this.setState({ questions });
  }

  render() {
    const { questions } = this.state;
    const userSelection = {answers: this.userSelection(questions.length)};
    console.log(userSelection);

    return (
      <Formik enableReinitialize={true} initialValues={userSelection}>
        {({ values, handleBlur, handleChange, handleSubmit, isSubmitting }) => (
          <form onSubmit={handleSubmit}>
            {questions.map((q, index) => (
              <div className="card" key={index}>
                <div className="card-header">Question {index + 1}</div>
                <div className="card-body">
                  <h6 className="card-title">{q.question}</h6>
                  <div className="question-choices px-2">
                    {q.choices.map((choice) => (
                      <div className="form-check" key={choice.option}>
                        <input
                          type="radio"
                          id={choice.option}
                          className="form-check-input"
                          name={`values.answers[${index}].answer`}
                          value={choice.option}
                          checked={
                            values.answers && values.answers[index]
                              ? values.answers[index].answer ===
                                choice.option
                              : false
                          }
                          onChange={handleChange}
                          onBlur={handleBlur}
                        />
                        <label
                          className="form-check-label clickable"
                          htmlFor={choice.option}
                        >
                          <span className="mr-2">{choice.option} )</span>{" "}
                          {choice.answer}
                        </label>
                      </div>
                    ))}
                  </div>
                </div>
              </div>
            ))}
            <pre>{JSON.stringify(values, null, 2)}</pre>
            <button
              type="submit"
              className="btn btn-primary"
              disabled={isSubmitting}
            >
              Submit
            </button>
          </form>
        )}
      </Formik>
    );
  }
}

export default Questions;

当我单击单选按钮时,我希望将每个问题的 属性 答案设置为所选值,但这不起作用。我不知道我到底做错了什么。将不胜感激。

您的问题是 inputname 属性错误,因为您的数据模型中没有 values

只需将其从名称中删除:

answers[${index}].answer 而不是 values.answers[${index}].answer

<input
  type="radio"
  id={choice.option}
  className="form-check-input"
  name={`answers[${index}].answer`}
  value={choice.option}
  checked={
    values.answers && values.answers[index]
      ? values.answers[index].answer === choice.option
      : false
  }
  onChange={handleChange}
  onBlur={handleBlur}
/>;

这是 CodeSandbox

中的工作示例