TanStack Query
useMutation
Query vs mutation, alap példa, invalidateQueries, optimistic update.
useMutation
Query vs mutation
| useQuery | useMutation | |
|---|---|---|
| Cél | adatok lekérése | adatok módosítása |
| HTTP | GET | POST/PUT/PATCH/DELETE |
| Futtatás | automatikus | csak mutate()-re |
| Cache | igen | nem (csak invalidál) |
Alap példa
import { useMutation, useQueryClient } from '@tanstack/react-query'
async function createUser(userData) {
const res = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(userData),
})
if (!res.ok) throw new Error('Nem sikerült a mentés')
return res.json()
}
function CreateUserForm() {
const queryClient = useQueryClient()
const mutation = useMutation({
mutationFn: createUser,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['users'] })
},
})
return (
<button
onClick={() => mutation.mutate({ name: 'Kiss Péter', email: 'peter@example.com' })}
disabled={mutation.isPending}
>
{mutation.isPending ? 'Mentés...' : 'Mentés'}
</button>
)
}Optimistic update – röviden
const mutation = useMutation({
mutationFn: updateTodo,
onMutate: async (updatedTodo) => {
await queryClient.cancelQueries({ queryKey: ['todos'] })
const previousTodos = queryClient.getQueryData(['todos'])
queryClient.setQueryData(['todos'], (old) =>
old.map(todo => todo.id === updatedTodo.id ? { ...todo, ...updatedTodo } : todo)
)
return { previousTodos }
},
onError: (err, updatedTodo, context) => {
queryClient.setQueryData(['todos'], context?.previousTodos)
},
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ['todos'] })
},
})📝 Összefoglaló
useMutation= módosítások (nem cache-elése).- Mindig invalidáld a kapcsolódó listákat mutation után.
- Optimistic update = azonnali UI frissítés rollback támogatással.