如何使用反应将输入输入到结构化数组(嵌套),数组大小将动态决定

How to take input to a structured array(nested) using react, Array size will be dynamically decided

我想从用户那里获取这些格式的输入

"questions":[
        {"question": "Trial question","options":[{"A":"hi","B":"hi","C":"hi","D":"hi"}], "ans":"A","marks":5},
        {"question": "Trial question2","options":[{"A":"hi","B":"hi","C":"hi","D":"hi"}], "ans":"A","marks":1},
        {"question": "Trial question2","options":[{"A":"hi","B":"hi","C":"hi","D":"hi"}], "ans":"A","marks":2}
    ]

这里的数组大小是动态的,用户可以输入n个这个结构。(这里的大小是3)

我正在尝试以这种方式获取输入

constructor() {
    super();
    this.state = {
      name: "",
      subject: "",
      numQuestion: 0,
      totalNumQuestion: "",
      questions: [
        {
          question: "",
          options: [
            {
              A: "",
              B: "",
              C: "",
              D: "",
            },
          ],
          marks: "",
          ans: "",
        },
      ],
    };
    this.handleSubmit = this.handleSubmit.bind(this);
  }

这里我按照以下方式进行输入

for (let i = 1; i <= this.state.numQuestion; i++) {
      inputs.push(
        <input
          placeholder="Question name"
          name={`question`}
          onChange={this.onChange}
          required
        />,
        <br />,
        <input
          placeholder="Option A"
          name={`A`}
          onChange={this.onChange}
          required
        />,

        <input
          placeholder="Option B"
          name={`B`}
          onChange={this.onChange}
          required
        />,

        <input
          placeholder="Option C"
          name={`C`}
          onChange={this.onChange}
          required
        />,

        <input
          placeholder="Option D"
          name={`D`}
          onChange={this.onChange}
          required
        />,
        <br />,
        <input
          placeholder="Answer"
          name={`ans`}
          onChange={this.onChange}
          required
        />,
        <br />,
        <input
          placeholder="Marks"
          name={`marks`}
          onChange={this.onChange}
          required
        />,
        <br />
      );

这是行不通的。我如何修改代码以实现上面指定结构中的数据

当您的状态变得如此复杂时,最好使用 useReducer 钩子。 在这里您可以创建一个商店(您的问题数组),然后编写不同的操作来对您的状态执行不同的操作。 这是使用 Reducer 的 link : https://reactjs.org/docs/hooks-reference.html#usereducer

您可以使用上面的示例 link 来满足您的需要。

您首先需要根据numberofQuestions初始化componentDidMount中的问题状态,我发现当前状态的问题数量为零,不确定您是从用户输入中获取还是永久设置来自你的代码。

componentDidMount(){
  let quest = [];
  for (let i = 0; i < this.state.numQuestion; i++) {
    quest.push(null)
  }
  this.setState({questions: quest})
}

对于选项输入和其他输入,您还需要不同的 onChangeonChangeOption 函数。

const onChange = (index, name, value) => {
  // declare a temp questions array
  const questions = this.state.questions
  // get the current question being changed
  const currentQuestion = questions[index];
  // if question has not been changed/added
  if (!currentQuestion) {
    const newQuestionObject = {
      question: "",
      options: [
        {
          A: "",
          B: "",
          C: "",
          D: "",
        },
      ],
      marks: "",
      ans: "",
    }

    newQuestionObject[name] = value;
    questions[index] = newQuestionObject;
    this.setState({ questions })
  } else {
    currentQuestion[name] = value;
    questions[index] = currentQuestion;
    this.setState({ questions })
  }
}

onChangeOption = (index, name, value) => {
  // declare a temp questions array
  const questions = this.state.questions
  // get the current question being changed
  const currentQuestion = questions[index];
  // if question has not been changed/added
  if (!currentQuestion && currentQuestion.question) {
    const newQuestionObject = {
      question: "",
      options: [
        {
          A: "",
          B: "",
          C: "",
          D: "",
        },
      ],
      marks: "",
      ans: "",
    }

    newQuestionObject.options[0][name] = value;
    questions[index] = newQuestionObject;
    this.setState({ questions })
  } else {
    currentQuestion.options[0][name] = value;
    questions[index] = currentQuestion;
    this.setState({ questions })
  }
}

然后您可以渲染元素


for (let i = 1; i <= this.state.numQuestion; i++) {
  inputs.push(
    <input
      placeholder="Question name"
      name={`question`}
      onChange={(e) => this.onChange(i, e.target.name, e.target.value)}
      required
    />,
    <br />,
    <input
      placeholder="Option A"
      name={`A`}
      onChange={(e) => this.onChangeOption(i, e.target.name, e.target.value)}
      required
    />,

    <input
      placeholder="Option B"
      name={`B`}
      onChange={(e) => this.onChangeOption(i, e.target.name, e.target.value)}
      required
    />,

    <input
      placeholder="Option C"
      name={`C`}
      onChange={(e) => this.onChangeOption(i, e.target.name, e.target.value)}
      required
    />,

    <input
      placeholder="Option D"
      name={`D`}
      onChange={(e) => this.onChangeOption(i, e.target.name, e.target.value)}
      required
    />,
    <br />,
    <input
      placeholder="Answer"
      name={`ans`}
      onChange={(e) => this.onChange(i, e.target.name, e.target.value)}
      required
    />,
    <br />,
    <input
      placeholder="Marks"
      name={`marks`}
      onChange={(e) => this.onChange(i, e.target.name, e.target.value)}
      required
    />,
    <br />
  );
}