Sometimes you want to use useEffect() to catch a change in a state, but only after the initial value has been set. For example, you have a state called selectedId, and you want to do something when the value changes.

You may have defined the state as follows, with an initial value:

const [selectedId, setSelectedId] = useState<number>(0);

To act on changes to selectedId, you configured a useEffect() statement as follows:

useEffect(() => {
  console.log(`selectedId has changed to ${selectedId}. Or the initial value is being set.)`);
}, [selectedId]);

This works fine for most cases, but the effect fires on every change as well as when the state is being set to its initial value.
What if we only want to detect changes after the initial value is set?

Instead of useEffect(), we can use a custom hook:

function useDidUpdateEffect(fn, inputs) {
  const isMountingRef = useRef(false);

  useEffect(() => {
    isMountingRef.current = true;
  }, []);

  useEffect(() => {
    if (!isMountingRef.current) {
      return fn();
    } else {
      isMountingRef.current = false;
    }
  }, inputs);
}

// Replace useEffect() with useDidUpdateEffect():
useDidUpdateEffect(() => {
  console.log(`selectedId has changed to ${selectedId}. This won't fire when the initial value is being set.`);
}, [selectedId]);

To make it more reusable, I like to add the custom hook in a separate file and import it when needed:

useDidUpdateEffect.tsx:

import React, { useEffect, useRef } from "react";

export const useDidUpdateEffect = (fn: any, inputs: React.DependencyList | undefined) => {
  const isMountingRef = useRef(false);
  useEffect(() => {
    isMountingRef.current = true;
  }, []);
  useEffect(() => {
    if (!isMountingRef.current) {
      return fn();
    } else {
      isMountingRef.current = false;
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, inputs);
}

Add required import statements to myComponent.tsx:

import { useDidUpdateEffect } from "hooks/useDidUpdateEffect";

useDidUpdateEffect(() => {
  console.log(`selectedId has changed to ${selectedId}. This won't fire when the initial value is being set.`);
}, [selectedId]);

Source: https://stackoverflow.com/a/53180013/4669143