2

I currently have a react hook that I'm creating that accepts a query object.

export function useMyQuery(query: QueryObjectType)
{
    React.useEffect(executeQuery, [ query ]);
    // ...
}

Unfortunately, any time my hook gets called as part of a re-render, despite query having never changed and still being the exact same object as before, I end up with an infinite loop.

I can resolve this by wrapping query with JSON.stringify(...), however I'm not sure if that's correct? Is there any preferred mechanism for testing equality for objects when being passed as a dependency to useEffect?

Alexander Trauzzi
  • 7,277
  • 13
  • 68
  • 112
  • 1
    Can you post the component which uses `useMyQuery`? – Paul Feb 10 '20 at 03:49
  • 1
    Here is another related question that might be helpful: https://stackoverflow.com/questions/54095994/react-useeffect-comparing-objects – bdanzer Feb 10 '20 at 03:49
  • @Paul - Totally picked up on what you were thinking there. And sure enough, yeah, the object I'm passing _is_ initialized in that component. So of course it's different every time. Problem solved I think – Alexander Trauzzi Feb 10 '20 at 04:06

1 Answers1

2

Adding a useState() should help. You would need to return the setter to allow re-querying from the parent.

useState(query) only fires on the first render, so _query remains the same until explicitly set.

export function useMyQuery(query: QueryObjectType)
{
    const [_query, setQuery] = useState(query);

    React.useEffect(executeQuery, [ _query ]);
    // ...

   return setQuery;
}
Richard Matsen
  • 20,671
  • 3
  • 43
  • 77