-1

I want to execute a function after functional component setstate has been completed. There are two ideas where we can use to know the state update has been completed

We can use useEffect to do a correct approach. But we cannot use in all the situation. For example

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

const func1 = ()=>{}
const func2 = ()=>{}
const func3 = ()=>{}

The setCount has been called inside func1 and func3. After setCount in func1, I need to call func2 but not in func3. If I use useEffect, whenever count has been updated the func2 will be called.

So I need a proper callback which need to be called after setState.

Can I execute a function after setState is finished updating?

Jeevanandan J
  • 144
  • 1
  • 8

1 Answers1

-1

With function components, you need to think in terms of a state machine. Your component function is called when state changes, and if you want to perform a side effect as a result of rendering that state, as you said you use useEffect. The key is to ensure that your state tells you what you need to do.

It sounds like you need a second state item that tells you whether to call func2. Very roughly:

function Example() {
    const [count, setCount] = useState(0);
    const [doTheCall, setDoTheCall] = useState(false);

    const func1 = () => {
        setCount((count) => {
            const value = /*...*/;
            setDoTheCall(true); // Indicate the call should be done
            return value;
        });
    };

    const func2 = () => {
        // ...
    }

    const func3 = () => {
        setCount(/*...*/);
    };

    useEffect(() => {
        // Do the call if we're supposed to
        if (doTheCall) {
            func2();
            setDoTheCall(false);
        }
    }, [doTheCall]);

    // ...
}

There I've used a simple flag, but another approach is to set the same value you're setting for count:

function Example() {
    const [count, setCount] = useState(0);
    const [countForCall, setCountForCall] = useState(false);

    const func1 = () => {
        setCount((count) => {
            const value = /*...*/;
            setCountForCall(value); // Set the value we compare with `count`
            return value;
        });
    };

    const func2 = () => {
        // ...
    }

    const func3 = () => {
        setCount(/*...*/);
    };

    useEffect(() => {
        // Do the call if we're supposed to
        if (count === countForCall) {
            func2();
            setCountForCall({}); // Will never match `count`
        }
    }, [count, countForCall]);

    // ...
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875