Run React useEffect() with dependencies just once

This is a very common question that can be answered in many ways. In this post, I will share a tip that I think is clean and elegant.

It’s piece of cake if we have no dependencies:

export default function myComponent() {
  useEffect(() => {
    // This runs only once
  }, []);
  return myComponent;
}

But unfortunately it’s more common to have several dependencies. Then we could do:

export default function myComponent() {
  const [data, setData] = useState({});
  
  useEffect(() => {
    if (_isObjEmpty(data)) {
      setData({ loaded: true });
      (async () => {
        try {
          const resp = await apiCall();
          setData(resp);
        } catch (e) {
          resp({ error: e });
        }
      })();
    }
  }, [data ...]);
  
  return myComponent;
}

In this way the data object will still have values whether the function has been invoked once or whether the call has given an error. If data is not empty the hook will do nothing. That’s all.

Side effect of an elixir of youth. Monkey Business, Howard Hawks 1952

Irene Iaccio

Freelance web developer

Subscribe to the monthly digest!

I'll use your email only to send you the latest posts once a month.