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>
)
}