How to distinguish if useEffect is triggered by route change

Viewed 1618

As I know useEffect can be triggered by the following conditions

  1. dependencies change
  2. Route change
  3. Initial render

I have the following component, data is a complex object. When it is triggered by route change, the data prop has the cached value. Everything else such as state, ref get reset.

const App = memo(({ data }}) => {
  useEffect(() => {
     // if triggered by route change, do thing
     
  }, [data]);

  return (<div />)
});

What is the best way to distinguish if useEffect invoked by route change?

1 Answers

Try to put location as a dependency:

useEffect(() => {
    // ...
}, [location]);

edit If you want to exclude this dependency, you can do:

const [flag, setFlag] = useState(true);

useEffect(() => {
    setFlag(false);
}, [location]);

useEffect(async () => {
    await setTimeout(() => undefined, 500); //sleep to wait for other useEffect() to set a flag or not
    
    if (flag) { /* do sth that is not invoked by a location change */ }
    else {
        setFlag(true);
    }
}, [data]);

edit2

I've looked it up in the official docs https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state

This way you can construct a componentDidUpdate(prevProps) hook, so your code would look sth like:

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

useEffect(() => {
    const prevLocation = usePrevious(location);

    if (location === prevLocation)
        //the body of your function
}, [data]);
Related