T
TanStack•3y ago
extended-salmon

setQueryData is not mutating the state somehow or at least it is not trigerring a rerender

Hello I have the following query:
const useDocuments = (contracts?: IContract[]): UseQueryResult<IDocument[], void> => {
return useQuery({
queryKey: ['documents', contracts],
queryFn: async () => await mapDocuments(contracts),
onSuccess: (data) => data,
onError: (error) => console.error(error)
});
};
const useDocuments = (contracts?: IContract[]): UseQueryResult<IDocument[], void> => {
return useQuery({
queryKey: ['documents', contracts],
queryFn: async () => await mapDocuments(contracts),
onSuccess: (data) => data,
onError: (error) => console.error(error)
});
};
And I have build a mutator for a document, if a user views the document I want to mark in the db and make a post request. I then want onSuccess to mutate the one document inside my list of documents
const useSetDocumentDisplayed = (documentId: string) => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async () => await setDocumentAsDisplayed(documentId),
onSuccess: (response) => {
console.log('response', response);
const data = response?.data;
if (!data) return;
queryClient.setQueryData(['documents', { id: data.id }], (oldData) => {
const oldDataFreezed = Object.freeze(oldData);
console.log('oldDataFreezed', oldDataFreezed);
console.log('oldData', oldData);

return {
//@ts-ignore
...oldData,
...data,
displayedAt: data.displayedAt
};
});
}
});
};
const useSetDocumentDisplayed = (documentId: string) => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async () => await setDocumentAsDisplayed(documentId),
onSuccess: (response) => {
console.log('response', response);
const data = response?.data;
if (!data) return;
queryClient.setQueryData(['documents', { id: data.id }], (oldData) => {
const oldDataFreezed = Object.freeze(oldData);
console.log('oldDataFreezed', oldDataFreezed);
console.log('oldData', oldData);

return {
//@ts-ignore
...oldData,
...data,
displayedAt: data.displayedAt
};
});
}
});
};
Am I doing something basic wrong here? It is the first time working with tanstack query for me.
7 Replies
passive-yellow
passive-yellow•3y ago
The query keys do not match. Above is an array, below an object
extended-salmon
extended-salmonOP•3y ago
🤔 Okay, sorry to ask this but shouldn't the query keys not always be a string[]|number[] ? ['documents', { id: data.id }] => this does infact give me the correct data set of the array 🤔 let me check again. How would matching keys look like?
passive-yellow
passive-yellow•3y ago
In useQuery contracts is an array… … and below in useMutation it is not
extended-salmon
extended-salmonOP•3y ago
u mean because of { id: data.id }
passive-yellow
passive-yellow•3y ago
Yes this is not an array. IContract[] is an array
extended-salmon
extended-salmonOP•3y ago
Hmm then my general set up is maybe wrong? I have two apis one will return me all documents based on contract /contracts/:contractId/documnts My mutation is document specific though => displayed/documents/documentId <- returns the manipulated document In my useDocuments I am building a IDocuments[] array, which holds all documents in disregard of the contract origin. I want to manipulate this array and update the displayed IDocument { id: data.id } <- I thought this is meant to look through my results of my useDocuments and return me the thing where the ids match okay I got it now thank you So the contracts also come from a differnt useQuery. What is best practice here then. I am now doing this:
const { data } = useContracts();
const { mutate } = useSetDocumentDisplayed(documentId, data ?? []);
const { data } = useContracts();
const { mutate } = useSetDocumentDisplayed(documentId, data ?? []);
passive-yellow
passive-yellow•3y ago
Looks good to me 🙂 For more best practice read blog: tkdodo.eu

Did you find this page helpful?