Expose setData from useQuery #4483
Replies: 3 comments 2 replies
-
yeah, we've discussed this before somewhere. proper typings is the biggest approach for this solution. However, one thing I'm unsure is the actual use-case: You don't really have a useQuery and a useMutation in the same component, or even directly in the component, in a real app. The preferred approach is to create custom hooks. So then you need to take the setData function that your custom hook returns and pass it to your custom mutation hook:
not sure if that would be easy to type, or if that would be better than calling This gets worse if the mutation lives in a different component than the query, which is often the case for more complex uis where they are split up in different component. One I'm not opposed to adding this though, just want to understand the rationale apart from a todo-list example :) |
Beta Was this translation helpful? Give feedback.
-
After using React Query in our project for about two years, in my humble opinion the lack of typing on I agree with @TkDodo that exposing // queries.ts
const useTodo = (id: number) => useQuery({
queryKey: ["todo", id],
queryFn: () => { ... },
});
// mutations.ts
const useUpdateTodo = (id: number) => useMutation({
mutationFn: () => { ... },
onSuccess: (data) => {
const { setData } = useTodo(id); // won't work
setData(data);
},
}); One could make the Alternatively, since const useUpdateTodo = (id: number) => {
const { setData } = useTodo(id);
return useMutation({
mutationFn: () => { ... },
onSuccess: (data) => setData(data),
});
}; However, one problem I can see with this approach is that the call to I've also been experimenting with ideas to define queries just as a const todoQuery = (id: number): UseQueryOptions<Todo, Error, Todo, string[]> => ({
queryKey: ["todo", id],
queryFn: () => { ... },
}); That way, one can both easily call the // MyComponent.tsx
const { data, isLoading } = useQuery(todoQuery(props.todoId));
// mutations.ts
function setDataSafely<
TQueryFnData = unknown,
TError = unknown,
TData = TQueryFnData,
TQueryKey extends QueryKey = QueryKey
>(
options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
data: TData
) {
return queryClient.setQueryData<TData>(options.queryKey!, data);
}
const updateTodo = (id: number): UseMutationOptions<UpdateTodoResponse, Error, number, unknown> => ({
mutationFn: () => { ... },
onSuccess: (data) => {
setQueryDataSafely(todoQuery(id), data); // will work
setQueryDataSafely(todoQuery(id), { foo: "bar" }); // will not work
},
}); While this approach is nice because you can extract things like |
Beta Was this translation helpful? Give feedback.
-
I am trying to use setData now is it removed from tanstack ? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
While working on some stuff I needed to do a query data update after a mutation, so I followed an example from the documentation, but I felt like it could be simplified.
Take a look at the example from the docs:
And here is my proposition:
As you can see an instance of Query Client is no longer needed as
setData
is directly accessible fromuseQuery
. You also do not need to pass any key assetData
would be bound to a query. Another bonus is proper typing out of the box, asqueryClient.setQueryData
does not know anything about query type by default.What do you think?
Beta Was this translation helpful? Give feedback.
All reactions