본문으로 건너뛰기

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&lt;TData, TError, TVariables, TOnMutateResult>

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

queryClient?​

QueryClient

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

반환값​

UseMutationResult&lt;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>
)
}