79288797

Date: 2024-12-17 17:15:28
Score: 0.5
Natty:
Report link

I want to be sure that when showComponentProp is updated, that the first useEffect updates the state before the second useEffect is run.

The first useEffect hook's callback will certainly enqueue the isVisible state update before the second useEffect hook is called.

I understand that useEffect hooks are run in the order they appear in the component body, however, as these contain setState functions, I'm not 100% sure of the behaviour. I don't want there to be a race condition between the two setState functions in the useEffect hooks.

All React hooks are called each render cycle, in the order they are defined. If showComponentProp changes, then because it is included in the dependency array of both useEffect hooks it will trigger the both useEffect hooks' callbacks, in the order they are defined.

Could someone please clarify the exact order of the useEffects being called and when the component is rerendered in this case. For instance, is the first effect called, and when the isVisible state is updated, does the component rerender before the second effect is called? In that case will both effects be run again after the rerender, or just the second effect as the first effect was called previously.

  1. The component will render and call all React hooks, in order.
  2. At the end of the render cycle the enqueued useEffect hook callbacks will be called, in order.
    1. Effect #1 callback will enqueue an isVisible state update to update to the current showComponentProp value.
    2. Effect #2 callback will check the current showComponentProp and timerProp values, and if both are truthy enter the if-block and instantiate the timeout to enqueue another isVisible state update to false, and return a useEffect hook cleanup function.
  3. The enqueued state updates will be processed and trigger a component rerender:
    1. Back to step 1 above to repeat the process
    2. The running timeout then either:
      • expires after timerProp ms and calls the callback to enqueue another isVisible state update to false, and trigger another component rerender, e.g. back to step 1 above.
      • cancelled by the cleanup function before expiration

In any case, both useEffect hooks will be called each and every render cycle, and the callbacks called only when the dependencies change.

However, I suspect you could accomplish this all in a single useEffect hook, which may make understanding the logic and flow a bit easier.

const [isVisible, setIsVisible] = useState(showComponentProp);

// Run effect when either showComponentProp or timerProp update
useEffect(() => {
  // Only instantiate timeout when we've both truthy
  // showComponentProp and timerProp values
  if (showComponentProp && timerProp) {
    // Enqueue isVisible state update "now"
    setIsVisible(true);

    // Enqueue timeout to enqueue isVisible state update "later"
    const timeout = setTimeout(() => setIsVisible(false), timerProp);

    return () => clearTimeout(timeout);
  }
}, [showComponentProp, timerProp]);
Reasons:
  • RegEx Blacklisted phrase (2.5): Could someone please clarify
  • RegEx Blacklisted phrase (1): I want
  • Long answer (-1):
  • Has code block (-0.5):
  • Contains question mark (0.5):
  • High reputation (-2):
Posted by: Drew Reese