Skip to content
Advertisement

Equivalent of setState callback with React hooks

I have a modal with a list of answers. I can either click an answer to select it, then click a button to confirm my choice. Or I can double-click an answer to select it and confirm.

I’m having trouble properly handling the double-click case.

With React class components, I would have used setState()‘s callback like this:

setState({selectedAnswer: answer}, confirm)

But right now, I only figured out the following:

const MyModal = ({hide, setAnwser}) => {
  const [selectedAnswer, setSelectedAnswer] = useState(null);
  const [isSelectionDone, setIsSelectionDone] = useState(false);

  const confirm = () => {
    if (!selectedAnswer) {
      return;
    }

    setAnwser(selectedAnswer);
    hide();
  };

  const handleAnswerOnClick = (answer) => {
    setSelectedAnswer(answer);
  };

  const handleAnswerOnDoubleClick = (answer) => {
    setSelectedAnswer(answer);
    setIsSelectionDone(true);
  };

  useEffect(confirm, [isSelectionDone]);

  return (
    <div>
      <div>{answers.map((answer) => <MyAnswer
        isSelected={answer.id === selectedAnswer?.id}
        key={answer.id}
        answer={answer}
        onClick={handleAnswerOnClick}
        onDoubleClick={handleAnswerOnDoubleClick}/>)}</div>
      <button onClick={confirm}>Confirm</button>
    </div>
  );
}

I strongly suspect that there’s a nicer/better way of doing it.

Maybe a simple:

const MyModal = ({hide, setAnwser}) => {
  const [selectedAnswer, setSelectedAnswer] = useState(null);

  const confirm = () => {
    if (!selectedAnswer) {
      return;
    }

    setAnwser(selectedAnswer);
    hide();
  };

  const handleAnswerOnClick = (answer) => {
    setSelectedAnswer(answer);
  };

  const handleAnswerOnDoubleClick = (answer) => {
    setAnwser(answer);
    hide();
  };

  return (
    <div>
      <div>{answers.map((answer) => <MyAnswer
        isSelected={answer.id === selectedAnswer?.id}
        key={answer.id}
        answer={answer}
        onClick={handleAnswerOnClick}
        onDoubleClick={handleAnswerOnDoubleClick}/>)}</div>
      <button onClick={confirm}>Confirm</button>
    </div>
  );
}

Which way is better?

Advertisement

Answer

There is no similar set state in hooks (which fires callback after state is set). But, you could apply following refactor:

 const confirm = (sAnswer = selectedAnswer) => {
    if (!sAnswer) {
      return;
    }

    setAnwser(sAnswer);
    hide();
  };

And then

 const handleAnswerOnDoubleClick = (answer) => {
    setSelectedAnswer(answer);
    confirm(answer);
  };
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement