0

I have an form with radio inputs. Each time the user selects on option, I must update the array containing the answers to the questions overriding old answers if it is the same question the user answered. So I have this useState that, in my thought, would map the old values of answers, map if the answer to the question is already there and Object.assign() it, otherwise if it is a new answer to a new question, then just return the answer. But it only returns the default array. If it is initialized like [{}] it returns Array[{}]. If it is [], returns Array[]

State is const [answers, setAnswers] = setState([])

  const handleCheckbox = (e, question) => {
    const newAnswer = { choice: e.target.id, question: question.uuid };

    setAnswers(
      [...answers],
      answers.map(
        answer =>
          answer.question === newAnswer.question ?
          Object.assign(answer, newAnswer): 
          newAnswer
      )
    );
  };

Expected: answers: [{id: 1}, {id: 2},...] without repeating those already there.

Actual: Array[]

1
  • You cannot create an array with this shape [answerQuestion1: {}, answerQuestion2:{},...]. Maybe more code will help us understand the issue better. A codesandbox will be greatly appreciated Commented Nov 2, 2019 at 15:36

1 Answer 1

1

Not sure what you are trying to do, you are calling the updater setAnswers with 2 arguments whereas it take a single one. Your exepected result [answerQuestion1: {}, answerQuestion2:{},...] is not valid JSON format and you used setState instead of useState.

I think you should restructure your model, why not use an object for the state variable answers, it would be like this :

const [answers, setAnswers] = useState({});

const handleCheckbox = (e, question) => {
  const id = question.uuid;
  const value = e.target.id; // Maybe you could use e.target.value or e.target.name

  setAnswers(prevAnswers => ({
     ...prevAnswers,
     [id]: value
  }));
};
Sign up to request clarification or add additional context in comments.

6 Comments

Yes. I've mistyped setState() instead o useState(). The original code is right.
It works! But still have a slightly problem. When the event is triggered the first time, the object remains empty, only after the first triggering it updates de object with actual values.
I don't really understant what is the problem ? you mean the first event doesn't update the state variable ? How did you check that ? Maybe the problem comes from the code which produces the rendering ?
I'm using id because of the structure of my choice object. Choices are unique. The e.target.value repeat over other questions, but I could use e.target.name. Is there a specific reason to use value or name instead of id?
be aware that setAnswers is asynchronous. If you add a console.log just after the setAnswers, you will not see the updated answers
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.