본문으로 건너뛰기

useMutation

function useMutation<TData, TError, TVariables, TOnMutateResult>(options, queryClient?): UseMutationResult<TData, TError, TVariables, TOnMutateResult>;

정의 위치: preact-query/src/useMutation.ts:191

쿼리와 달리 뮤테이션은 일반적으로 데이터를 생성/업데이트/삭제하거나 서버 측 부수 효과를 수행하는 데 사용됩니다. 이를 위한 훅은 useMutation입니다.

타입 매개변수

TData

TData = unknown

TError

TError = Error

TVariables

TVariables = void

TOnMutateResult

TOnMutateResult = unknown

매개변수

옵션

UseMutationOptions<TData, TError, TVariables, TOnMutateResult>

사용할 UseMutationOptions입니다 — useMutation에 전달할 수 있는 모든 항목입니다.

queryClient?

QueryClient

사용자 지정 QueryClient를 사용하려면 이를 사용합니다. 그렇지 않으면 가장 가까운 컨텍스트의 항목이 사용됩니다 사용됩니다.

반환값

UseMutationResult<TData, TError, TVariables, TOnMutateResult>

mutate/mutateAsync는 호출별 onSuccess/onError/onSettled 콜백도 두 번째 인수로 허용합니다 인수로, 공유된 대상에 결합하지 않고 호출 지점의 부수 효과(예: 탐색)를 트리거하는 데 유용합니다 뮤테이션 정의입니다. 여러 요청을 하면 onSuccess는 사용자가 실행한 가장 최근 호출 이후에만 실행됩니다 만들었습니다.

참조

여러 useMutation 호출 지점에서 이러한 옵션을 공유하거나 조회하려면 mutationOptions를 사용합니다 해당 mutationKey를 통해 다른 곳에서 뮤테이션을 조회합니다(예: useMutationState 사용).

예시

import { useMutation, useQueryClient } from '@tanstack/preact-query'

function AddTodo() {
const queryClient = useQueryClient()

const addMutation = useMutation({
mutationFn: addTodo,
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
})

return (
<button
onClick={() =>
addMutation.mutate('Item', {
onError: (error) => console.error('Failed to add item:', error),
})
}
>
Add
</button>
)
}

뮤테이션을 단순히 실행하는 대신 뮤테이션 자체의 상태를 렌더링하기:

import { useMutation, useQueryClient } from '@tanstack/preact-query'

function AddTodo() {
const queryClient = useQueryClient()

const addMutation = useMutation({
mutationFn: addTodo,
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
})

return (
<div>
{addMutation.isPending ? (
'Adding todo...'
) : (
<>
{addMutation.isError ? (
<div>An error occurred: {addMutation.error.message}</div>
) : null}
<button onClick={() => addMutation.mutate('Item')}>Add</button>
</>
)}
</div>
)
}

onMutate를 통한 낙관적 업데이트 및 onError 시 롤백:

import { useMutation, useQueryClient } from '@tanstack/preact-query'

function AddTodo() {
const queryClient = useQueryClient()

const addMutation = useMutation({
mutationFn: addTodo,
onMutate: async (newTodo) => {
await queryClient.cancelQueries({ queryKey: ['todos'] })
const previousTodos = queryClient.getQueryData<Array<string>>(['todos'])

queryClient.setQueryData<Array<string>>(['todos'], (old) => [
...(old ?? []),
newTodo,
])

// Passed to `onError` as `context` if the mutation fails.
return { previousTodos }
},
onError: (_err, _newTodo, context) => {
queryClient.setQueryData(['todos'], context?.previousTodos)
},
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ['todos'] })
},
})

return (
<button onClick={() => addMutation.mutate('Item')}>Add</button>
)
}

mutate의 호출별로 전달된 콜백은 마지막 호출에서만 실행됩니다 — mutateAsync는 다음을 제공합니다 대신 호출마다 Promise를 반환하므로, 모든 Promise를 기다릴 수 있습니다:

import { useMutation, useQueryClient } from '@tanstack/preact-query'

function AddTodos() {
const queryClient = useQueryClient()

const addMutation = useMutation({
mutationFn: addTodo,
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
})

async function handleAddAll(todos: Array<string>) {
try {
await Promise.all(todos.map((todo) => addMutation.mutateAsync(todo)))
} catch (error) {
console.error('Failed to add todos:', error)
}
}

return (
<button onClick={() => handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])}>
Add all
</button>
)
}

위 뮤테이션 중 일부가 다른 뮤테이션과 독립적으로 실패할 수 있고 어떤 뮤테이션이 실패했는지 알고 싶다면 그렇게 했습니다 — 첫 번째 항목이 거부되는 순간 해당 정보를 잃는 대신 — Promise.all을 다음으로 교체합니다 Promise.allSettled:

import { useMutation, useQueryClient } from '@tanstack/preact-query'

function AddTodos() {
const queryClient = useQueryClient()

const addMutation = useMutation({
mutationFn: addTodo,
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
})

async function handleAddAll(todos: Array<string>) {
const addResults = await Promise.allSettled(
todos.map((todo) => addMutation.mutateAsync(todo)),
)

addResults.forEach((addResult, index) => {
if (addResult.status === 'rejected') {
console.error(`Failed to add "${todos[index]}":`, addResult.reason)
}
})
}

return (
<button onClick={() => handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])}>
Add all
</button>
)
}