Skip to main content

How to use objects and arrays as React hook dependencies

This solved a problem I spent hours stuck on during one work day.

I made a custom hook (useQueryParam ) that returned either a primitive value, an array or an object depending on which query param was passed in (e.g. useQueryParam('foo') returned a string but useQueryParam('bar') returned an array of strings).

A useEffect hook made a call to the /baz endpoint and passed in a number of query param values as arguments. As a result, those useQueryParam values were included in the useEffect dependency array.

However, the hook called itself repeatedly even though the values of those params weren’t changing.

After hours of eliminating every other possibility, I confirmed the issue was the array and object dependecies since when I excluded them, the re-rendering bug stopped.

I did some research and found Ben Ilegbodu’s article, which offered a number of solutions, ending with one that leverages (abuses) the useRef hook. He then pointed to the react-use/useDeepCompareEffect hook that packages that solution.

I look at the source code and saw it was minimal. I tried it and it worked right away.

This hook is a big help! I hope it helps you too.

Further reading

Inbox

  • TODO: validate which data types this issue occurs with:
    • the docs for useDeepCompareEffect say it should only matter for arrays that contain objects (rather than all arrays)
    • that’s different than my understanding (all non-primitive values have this issue)
    • experiment with some outputs that prove which is the case
    • include those demonstrations in the post/note