'Why is data of the query result, and refetch's result not equal in apollo client?
I was having synchronisation issues with using apollo client queries the traditional way. Using useEffect when data changes, and make my actions was causing flashing screens, so I decided to use a different scenario:
const [initGetItems, { refetch: refetchItems, data, loading }] =
useGetItemsLazyQuery({
fetchPolicy: 'network-only',
notifyOnNetworkStatusChange: true,
});
const getItems = (variables: GetItemsQueryVariables) =>
(!data && !loading
? initGetItems({ variables: variables })
: refetchItems(variables)
).then(({ data }) => {
return data?.getItems || [];
});
to promisify a lazy query, and make state changes at the same time with the data. I'm storing the items in react state, which is more reliable for my case.
There's a case though in my app where the data is changed from outside of getItems, by refetchQueries after a mutation. I have to update my react state with the new result, but the state currently is set by getItems. My idea was to compare the react state of items with the data.getItems. I would expect that the object references are equal, but they are not. If we extend the above code like:
const [items, setItems] = useState<GetItemsQuery['getItems']>([])
const [initGetItems, { refetch: refetchItems, data, loading }] =
useGetItemsLazyQuery({
fetchPolicy: 'network-only',
notifyOnNetworkStatusChange: true,
});
const getItems = (variables: GetItemsQueryVariables) =>
(!data && !loading
? initGetItems({ variables: variables })
: refetchItems(variables)
).then(({ data }) => {
setItems(data?.getItems || [])
return data?.getItems || [];
});
console.log(items, data?.getItems, items === data?.getItems);
data?.getItems, and items are never equal. I'm not sure how apollo client works behind the scenes, but I would expect the data returned as a promise is the same as data, from the second part of the tuple returned by the query hook especially because the results are cached.
When I do the console log, the objects inside the array (seem) equal.
Am I doing something wrong, or shouldn't expect the two datas to be equal?
Solution 1:[1]
Short answer is that you're comparing the memory address of the variables and not the contents of the variables. Because you're going to call getItems on every re-render, that address will change every re-render. It's not clear what's going on inside those functions; but you could look into using the useRef hook to save state inside the current property and compare those values across renders.
This type of thing is generally pushed into a useEffect() with dependencies on the bits that can change.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Dave |
