Добавление элементов массива через несколько полей формы в React

#javascript #arrays #reactjs #forms #react-state-management

#javascript #массивы #reactjs #формы #управление состоянием реакции

Вопрос:

Я работаю над проектом приложения для викторины, чтобы научиться реагировать. Я столкнулся с ситуацией, когда мне нужно сохранить неправильные параметры в вопросе викторины в массиве. И последующая передача информации в базу данных. Это пример формата JSON.

 {       
        incorrect_answers:["Jeff Bezos","Satya Nadela","Bill Gates"] }
  

Неправильный ответ — это массив, и значение необходимо вводить через отдельные текстовые поля для каждого неправильного параметра, подобного этому.
форма ввода опции

Часть, в которой я застрял, — это добавление их в массив, вот моя попытка.

 export default class CreateQuiz extends Component{
constructor(props){
    super(props);
   
          this.onChangedIncorrectAnswer=this.onChangedIncorrectAnswer.bind(this);
    this.onSubmit=this.onSubmit.bind(this);

    this.state={
        incorrect_answers:[]
    } 
    
    
}

onChangedIncorrectAnswer(e){
    const option=e.target.value
    this.setState({
        incorrect_answers:[...this.state.incorrect_answers,option]
    });
}


onSubmit(e){
    e.preventDefault();

    const quiz = {
        incorrect_answers:this.state.incorrect_answers
    }

    console.log(quiz);
    axios.post("http://localhost:3000/quizes",quiz)
    .then(res=>console.log(res.data));
    window.location='/quiz-list';
}

render(){
    return (
        <div>
            <h3>Create New Quiz</h3>
            <form onSubmit={this.onSubmit}>
           
                <div className="form-group">
                    <label>Incorrect Option 1</label>
                    <input type="text"
                        required
                        className="form-control"
                        value={this.state.incorrect_answers[0]}
                        onChange={this.onChangedIncorrectAnswer}
                        />
                </div>

                <div className="form-group">
                    <label>Incorrect Option 2</label>
                    <input type="text"
                        required
                        className="form-control"
                        value={this.state.incorrect_answers[1]}
                        onChange={this.onChangedIncorrectAnswer}
                        />
                </div>

                <div className="form-group">
                    <label>Incorrect Option 3</label>
                    <input type="text"
                        required
                        className="form-control"
                        value={this.state.incorrect_answers[2]}
                        onChange={this.onChangedIncorrectAnswer}
                        />
                </div>

            
                <div className="form-group">
                    <input type="submit" value="Submit Quiz" className="btn btn-primary"/>
                </div>

            </form>
        </div>
    )
}
  

}

Но форма работала не так, как ожидалось. Когда я ввожу содержимое для первого варианта в текстовое поле «Вариант 1», сохраняется только первый символ, оставшийся в «Варианте 2» и так далее.

Комментарии:

1. Не забудьте максимально упростить свой пример. Есть ли какие-либо части вашего примера, которые нам не нужно видеть? Вам также нужно объяснить, что на самом деле происходит. Добавляется ли что-нибудь в массив? Форма не отправляется правильно?

Ответ №1:

попробуйте это, это сработает!!

 export default class CreateQuiz extends Component {
constructor(props) {
super(props);

this.onChangedCorrectAnswer = this.onChangedCorrectAnswer.bind(this);
this.onChangedIncorrectAnswer = this.onChangedIncorrectAnswer.bind(this);
this.onSubmit = this.onSubmit.bind(this);

this.state = {
  category: "",
  correct_answer: "",
  difficulty: "",
  type: "",
  question: "",
  incorrect_answers: ["", "", ""]
  };
}

 onChangedCorrectAnswer(e) {
   this.setState({
  correct_answer: e.target.value
  });
 }

 onChangedIncorrectAnswer(e, index) {
  const option = e.target.value;
  const { incorrect_answers } = this.state;
  incorrect_answers[index] = option;
 this.setState({
  incorrect_answers
 });
}

onSubmit(e) {
  e.preventDefault();

const quiz = {
  category: this.state.category,
  correct_answer: this.state.correct_answer,
  incorrect_answers: this.state.incorrect_answers,
  difficulty: this.state.difficulty,
  type: this.state.type,
  question: this.state.question
};

console.log(quiz);
axios
  .post("http://localhost:3000/quizes", quiz)
  .then((res) => console.log(res.data));
window.location = "/quiz-list";
}

render() {
  return (
  <div>
    <h3>Create New Quiz</h3>
    <form onSubmit={this.onSubmit}>
      <div className="form-group">
        <label>Correct Answer</label>
        <input
          type="text"
          required
          className="form-control"
          value={this.state.correct_answer}
          onChange={this.onChangedCorrectAnswer}
        />
      </div>

      <div className="form-group">
        <label>Incorrect Option 1</label>
        <input
          type="text"
          required
          className="form-control"
          value={this.state.incorrect_answers[0]}
          onChange={(e) => this.onChangedIncorrectAnswer(e, 0)}
        />
      </div>

      <div className="form-group">
        <label>Incorrect Option 2</label>
        <input
          type="text"
          required
          className="form-control"
          value={this.state.incorrect_answers[1]}
          onChange={(e) => this.onChangedIncorrectAnswer(e, 1)}
        />
      </div>

      <div className="form-group">
        <label>Incorrect Option 3</label>
        <input
          type="text"
          required
          className="form-control"
          value={this.state.incorrect_answers[2]}
          onChange={(e) => this.onChangedIncorrectAnswer(e, 2)}
        />
      </div>

      <div className="form-group">
        <input
          type="submit"
          value="Submit Quiz"
          className="btn btn-primary"
        />
      </div>
    </form>
  </div>
);
  

}
}

Ответ №2:

Ваше состояние массива рассматривается только как одно состояние, почему бы вам не создать состояние на ходу, когда пользователь вносит какие-либо изменения во входные данные.

создайте объект состояния, подобный

 this.state = {incorrect_answers: {}}
  

В вашем onChangedIncorrectAnswer

 onChangedIncorrectAnswer(e){
    const option=e.target.value;
    const stateName = e.target.name;
    this.setState({
        incorrect_answers: {...this.state.incorrect_answers, [stateName]: option }
    });
}
  

используйте свой элемент формы в качестве имени добавления как уникального, которое будет использоваться в качестве состояния

 <div className="form-group">
    <label>Incorrect Option 1</label>
    <input name="incorrect_answers_0" type="text" required className="form-control" value={this.state.incorrect_answers[incorrect_answers_0]}
        onChange={this.onChangedIncorrectAnswer} />
</div>
  

используйте этот объект при сохранении

 onSubmit(e){
    let yourIncorrectAnswers = Object.values(this.state.incorrect_answers);
  })
    

}