Home > database >  Accessing input value in React using onChange function
Accessing input value in React using onChange function

Time:01-12

I'm working on an exercise in which I have to build a simple Quiz App, I have a few components (such as "question", "question-list" and "add-question"), in the "add-question" component I have a form to add a new question to the list and using a template we saw in class I'm trying to add the values the user adds to my Questions List, I succeeded in doing that with the regular parameters by naming the relevant input with the same "name" as the parameter name, but I'm trying to pass some values from the form into my "answers" array (which contains "text" (string), "correctAnswer"(boolean), I tried a few things but none of them worked and the last one I tried works only for the last input I filled but not for all 4 That's my code (Including my "question" format, the "onChange" function and the form):

function AddQuestion(props) {
  const [question, SetQuestion] = useState({
    title: "",
    description: "",
    answers: [
      { id: 0, text: "", correctAnswer: false }
      { id: 1, text: "", correctAnswer: false },
      { id: 2, text: "", correctAnswer: false },
      { id: 3, text: "", correctAnswer: false }],
    clicked: false});

  const onChange = (e) => {
    let firstAnswer, secondAnswer, thirdAnswer, fourthAnswer;

    if (e.target.name === "firstAnswer") {
      firstAnswer = e.target.value;
    }
    if (e.target.name === "secondAnswer") {
      secondAnswer = e.target.value;
    }
    if (e.target.name === "thirdAnswer") {
      thirdAnswer = e.target.value;
    }
    if (e.target.name === "fourthAnswer") {
      fourthAnswer = e.target.value;
    }

    let updated = {...question, answers: {
        0: { text: firstAnswer },
        1: { text: secondAnswer },
        2: { text: thirdAnswer},
        3: { text: fourthAnswer}}
    };

    updated[e.target.name] = e.target.value;
    SetQuestion(updated);
  };

  return (
    <div className={style.newQuestionForm}>
      <h1>Add a New Question</h1>
      <label>Title: <br /> <input type="text" name="title" onInput={onChange}/></label>
      <label>Description:<br/><input type="text" name="description" onInput={onChange}/></label>
      <label>First Answer:<br /><input type="text" name="firstAnswer" onInput={onChange}/></label>
      <label>Second Answer:<br/><input type="text" name="secondAnswer" onInput={onChange}/></label>
      <label>Third Answer:<br/><input type="text" name="thirdAnswer" onInput={onChange}/></label>
      <label>Fourth Answer:<br/><input type="text" name="fourthAnswer" onInput={onChange}/></label>
     
      <div className={style.btnDiv}>
        <button className={style.newQuestionBtn} onClick={() => props.onAdd(question)}> 
            Add New Question
        </button>
      </div>
    </div>
  );
}

CodePudding user response:

There was a problem when you are trying to save final object to state.

As you can see, you are trying to convert answersfrom array to dictionary:

 let updated = {...question, answers: {
        0: { text: firstAnswer },
        1: { text: secondAnswer },
        2: { text: thirdAnswer},
        3: { text: fourthAnswer}}
    };

In addition, you are losing more information about the answers, like id and correctAnswer

To solve this you must continue using an array instead of dictionary.

Furthermore I improved about the logic to save info to state.

I deleted variables about the answers to use unique object, updatedQuestion. This object contains previous value from state and then you can use your conditionals to check which answer it is and change only his text

 const onChange = (e) => {
  let updatedQuestion = {
      ...question
    };

    if (e.target.name === "firstAnswer") {
      updatedQuestion.answers[0].text = e.target.value;
    }
    if (e.target.name === "secondAnswer") {
      updatedQuestion.answers[1].text = e.target.value;
    }
    if (e.target.name === "thirdAnswer") {
      updatedQuestion.answers[2].text = e.target.value;
    }
    if (e.target.name === "fourthAnswer") {
      updatedQuestion.answers[3].text = e.target.value;
    }

    SetQuestion(updatedQuestion);
  };

Now if you try this method, when you add a question to your app, form works. You just need an extra checkbox to select which question is correct.

Let me know if you have any problem

  • Related