Lets say I have a /products endpoint and also /product/{id} and I’m populating a page using react query, by calling the /products
const products = useQuery('products', queryRepo.getAllProducts)
But I could also fetch an individual product using
useQuery(['product', productId], () => queryRepo.getProduct(productId));
So, I have a mutation to update, say, a product’s price, and using a mutation and optimistic updates (As per the react query docs)
The react query docs state this can be done as follows
useMutation(updateTodo, {
// When mutate is called:
onMutate: async newTodo => {
// Cancel any outgoing refetches (so they don't overwrite our optimistic update)
await queryClient.cancelQueries('todos')
// Snapshot the previous value
const previousTodos = queryClient.getQueryData('todos')
// Optimistically update to the new value
queryClient.setQueryData('todos', old => [...old, newTodo])
// Return a context object with the snapshotted value
return { previousTodos }
},
// If the mutation fails, use the context returned from onMutate to roll back
onError: (err, newTodo, context) => {
queryClient.setQueryData('todos', context.previousTodos)
},
// Always refetch after error or success:
onSettled: () => {
queryClient.invalidateQueries('todos')
},
})
What I want to happen, is to call the mutation (Which will update the price, and optimistically update the products array, and finally, query the data again)
However, as I have the ability to get ALL products or just 1, how can these best be ‘linked’ It seems a shame to pull all the data
My Questions are;
-
Is there a design / better design for this pattern? (I don’t want to call the ones by ID 50 times to load the page, but I also dont want to fetch 50 items at once to update 1 item)
-
Is it somehow possible to use the getProduct useQuery hook above to update the ‘products’ data state, because react-query knows that they are the same data. getAllProducts returns an array, would it be better to be an indexed object so getProduct can update an individual product?
-
In the case of the getProduct useQuery, is there a way to define this without a productId to tell react-query how to get an individual product.
Thanks. Maybe I’m hoping react-query is more clever than it is, or maybe I’m just confused !