Search code examples
javascriptreactjsreact-hooksuse-effect

How do I fire React useEffect hook only once after state change?


I am new to React hooks and I am not sure how to achieve following goal. Let's say I have state1 and state2, and I use useEffect hook to call asyncFn1 and update state1.

Now I want to wait for state1 change and use state1 value to call asyncFn2 and update both state1 and state2. This asnycFn1 and asyncFn2 should only be called once.

If I just use another useEffect to call asyncFn2, I won't get the state1 value. How do I solve that?

const [state1, setState1] = useState(null);
const [state2, setState2] = useState(null);

const asyncFn1 = async() => {
  // async call to get state 1 data
  // setState1
}

const asyncFn2 = async(_state1) => {
  // use state1 data to make async call to get state 2 data
  // state2 data will be used to update both state1 and state2
}

useEffect(() => {
  asyncFn1();
}, [])

Solution

  • What you need here is a useEffect which has your state1 in the useEffect dependency array, so to trigger it any time your state1 value changes, as such:

    useEffect(() => {
       state1 && asyncFn2()
    }, [state1])
    

    In case you want your asyncFn2 to trigger only once after you get the data for state1, you can just add a ref to check when that's being called:

    const dataLoaded = useRef(false)
    
    useEffect(() => {
       if(state1 && !dataLoaded.current) {
          asyncFn2()
       }
    }, [state1])
    
    const asyncFn2 = async () => {
       // Your logic here
    
       // Set dataLoaded on true once you have updated what you need successfully
       dataLoaded.current = true
    }