-
Couldn't load subscription status.
- Fork 8
Description
When handling mutations that return data used in existing queries, developers currently have two options:
- Trigger a full query refetch
- Manually update the query cache
Manual cache updates require accessing the queryClient and using setQueryData with hand-constructed query keys. This approach:
- Creates unnecessary complexity
- Increases potential for errors in key construction
- Reduces type safety
- Results in verbose, hard-to-maintain code
I think this is sometimes referred to as optimistic updates.
Proposed Solution
Add a setData method directly to the Query object, allowing developers to update query data without manually managing query keys or accessing the query client.
Current Implementation
<script lang="ts">
import { trpc } from "$src/lib/trpcClient";
import { getQueryKey } from "trpc-svelte-query-adapter";
import { useQueryClient } from "@tanstack/svelte-query";
import { writable } from "svelte/store";
const name = writable("John Doe");
const userQuery = trpc().user.getInfo;
const user = userQuery.createQuery(name);
const queryClient = useQueryClient();
const createGreeting = trpc().user.setAge.createMutation({
onSuccess: (data) => {
queryClient.setQueryData(
getQueryKey(userQuery, name, "query"),
(old: unknown) => {
if (typeof old !== "object") return old;
return { ...old, age: data.age };
}
);
},
});
</script>
<input bind:value={$name} />
<button onclick={() => $createGreeting.mutateAsync({ age: $user.age + 1 })}>
Birthday
</button>
<p>{$user.age}</p>Proposed Implementation
const createGreeting = trpc().user.setAge.createMutation({
onSuccess: (data) => {
user.setData(name, (old) => {
if (typeof old !== "object") return old;
return { ...old, age: data.age };
});
},
});Benefits
Developer Experience
- More intuitive API that aligns with developer expectations
- Significantly reduces boilerplate code
- Eliminates need to manually construct and manage query keys
- Keeps related functionality (query data and its updates) together
Type Safety & Reliability
- Better TypeScript inference since the query's data type is already known
- Reduces potential runtime errors from incorrect key construction
- Makes code more maintainable and easier to refactor
Performance
- No performance overhead compared to current approach
- Still allows for granular cache updates without full refetches
Implementation Details
The setData method would internally:
- Access the query client
- Construct the appropriate query key
- Update the cache with the provided data
This encapsulation ensures consistency and reduces the chance of errors while maintaining all existing functionality.
Migration Path
This addition would be fully backward compatible, allowing developers to gradually migrate existing code while maintaining support for the current approach.
(i won't have time to work on this, just flagging that it would be nice to have)