sho
sho

Reputation: 153

How to call function after setState() done

I created a function like this.

export function Counter() {

    const [count, setCount] = useState(0);

    const countUp = () => {
        setCount(count + 1);
    }

    const countUpAndShow = () => {
        setCount(count + 1);
        alert(count);
    }

    // I won't call after countUp function, call only countUpAndShow function.
    useEffect(() => {
        alert(count);
    },[count])

    return <div>
        <button onClick={countUp}>count up!</button>
        <button onClick={countUpAndShow}>show count!</button>
    </div>
}

I want to call alert(count) after setCount(). but alert(count) not show count correctly.

then, I use useEffect like above. but I want to call alert() only countUpAndShow function. how to solve it ?

Upvotes: 3

Views: 3469

Answers (2)

Drew Reese
Drew Reese

Reputation: 202608

There are multiple ways to solve for this. I will suggest using a React ref to toggle a show "state" so it can live outside the React component lifecycle and React hook dependencies. I also suggest using functional updates when incrementing a counter state value as this will correctly update from any previous state versus the state the callback was enqueued in. In other words it avoids stale state enclosures.

function Counter() {
  const show = useRef(false);
  const [count, setCount] = useState(0);

  const countUp = () => {
    setCount((count) => count + 1);
  };

  const countUpAndShow = () => {
    setCount((count) => count + 1);
    show.current = true;
  };

  useEffect(() => {
    if (show.current) {
      alert(count);
      show.current = false;
    }
  }, [count]);

  return (
    <div>
      <button onClick={countUp}>count up!</button>
      <button onClick={countUpAndShow}>show count!</button>
    </div>
  );
}

Edit how-to-call-function-after-setstate-done

Upvotes: 6

Prayag Choraria
Prayag Choraria

Reputation: 819

Try this.

export function Counter() {

    const [count, setCount] = useState(0);
    const [show, setShow] = useState(false);

    const countUp = () => {
        setCount(count + 1);
    }

    const countUpAndShow = () => {
        setCount(count + 1);
        setShow(true)
        alert(count);
    }

    // I won't call after countUp function, call only countUpAndShow function.
    useEffect(() => {
        if(show) {
            alert(count);
            setShow(false);
        }
    },[show])

    return <div>
        <button onClick={countUp}>count up!</button>
        <button onClick={countUpAndShow}>show count!</button>
    </div>
}

Upvotes: -1

Related Questions