admin管理员组

文章数量:1291128

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();
}, [])

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();
}, [])
Share Improve this question edited Apr 26, 2021 at 2:14 Orio Ryo asked Apr 25, 2021 at 7:01 Orio RyoOrio Ryo 1881 gold badge2 silver badges9 bronze badges 4
  • Why do you want to update state1 from asyncFn2? Does the input _state1 to asyncFn2 differ from the state you want to call setState1 with? – Patrick Roberts Commented Apr 25, 2021 at 7:10
  • 1 See stackoverflow./questions/59492626/…, same logic, have a ref which acts as "called once" flag. – Dennis Vash Commented Apr 25, 2021 at 7:29
  • @PatrickRoberts Yes the state 1 will cause different asyncFn2 result which will be used to update the state1 again. – Orio Ryo Commented Apr 26, 2021 at 2:10
  • @DennisVash thank you! useRef is exactly what I needed. – Orio Ryo Commented Apr 26, 2021 at 2:12
Add a ment  | 

3 Answers 3

Reset to default 9

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
}

I do this quite often and found that for me the most readable (and understandable) method is to use a hook that stores the previous value of something.

export function usePrevious(value) {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  }, [value]);
  return ref.current;
}

Then when I want create a side effect only when one specific value in my state changes I write:

const [fetching, setFetching] = useState(false);
const prevFetching = usePrevious(fetching);

useEffect(() => {
  if (prevFetching === true && fetching === false) {
    // Do something
  }
}, [fetching, prevFetching]);

To wait for the result of asyncFn1 to fetch the data for asyncFn2 you can use IIFE inside the useEffect and wait for asyncFn1 to plete executing and use the result to make the call to asyncFn2.

useEffect(() => {
    (async function(){
      const result1 = await asyncFn1();
      // Use the result to fetch the data for asyncFn2 
      const result2 = await asyncFn2();
      // Update both state1 and state2
     })()
    }, [])

本文标签: javascriptHow do I fire React useEffect hook only once after state changeStack Overflow