Gabriel Silva
Gabriel Silva

Reputation: 69

Updating state arrays with React Hooks

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[]

Upvotes: 0

Views: 344

Answers (1)

Olivier Boissé
Olivier Boissé

Reputation: 18163

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
  }));
};

Upvotes: 1

Related Questions