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

时间:2020-07-04 07:50:45

标签: reactjs 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;

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

1 个答案:

答案 0 :(得分:1)

您的问题是name的{​​{1}}属性错误,因为您的数据模型中没有input

只需将其从名称中删除:

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

values.answers[${index}].answer

这是CodeSandbox

中的有效示例