skip to Main Content

Based on the article outlined in the React docs: You Might Not Need An Effect, they explain that logic which should only be executed once should be wrapped in an init clause.

i.e.

// Will run init flow only once per application lifecycle

let didInit = false;

function App() {
  useEffect(() => {
    if (!didInit) {
      didInit = true;

      loadDataFromLocalStorage();
      checkAuthToken();
    }
  }, []);
}

Or:

// Will run init flow whenever component is mounted

function App() {
  const didInit = useRef(false);

  useEffect(() => {
    if (!didInit.current) {
      didInit.current = true;

      loadDataFromLocalStorage();
      checkAuthToken();
    }
  }, []);
}

However, if moved outside the effect, the behavior remains the same. So if the behavior’s the same, why would you need the hook?

2

Answers


  1. Moving the logic outside useEffect will result in a different behavior, leading to potential issues and bugs. You should always use useEffect for side effects to maintain predictable and stable component behavior.

    Login or Signup to reply.
  2. It is not about whether or no the logic runs. It is about when the logic runs and what it does.

    Putting things outside means the callback runs during rendering. And inside effect means it runs after the render.

    There is also the difference of intent. React component’s function body job is to return the UI representation. Side effects should ideally go inside useEffect callbacks. React team has been recommending this since beginning and it is becoming more important now with concurrent React, where rendering can be paused midway and started again. Then your sideEffecty code will run again and again.

    The same doc you refer to links to these:

    1. https://react.dev/learn/keeping-components-pure
    2. https://react.dev/learn/synchronizing-with-effects
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search