## React query mutation
### Mutation用於新增/更新/刪除
```
function App() {
const mutation = useMutation({
mutationFn: (newTodo) => {
return axios.post('/todos', newTodo)
},
})
return (
<div>
{mutation.isLoading ? (
'Adding todo...'
) : (
<>
{mutation.isError ? (
<div>An error occurred: {mutation.error.message}</div>
) : null}
{mutation.isSuccess ? <div>Todo added!</div> : null}
<button
onClick={() => {
mutation.mutate({ id: new Date(), title: 'Do Laundry' })
}}
>
Create Todo
</button>
</>
)}
</div>
)
}
```
### Mutation狀態
> 每個 useMutation 間的 state 是獨立的,保有各自的狀態
* ### isIdle - mutation未被執行且沒有其他狀態時,當reset時狀態也將變為Idle
* ### isLoading - mutation request過程
* ### isSuccess - mutation成功
* ### isError - mutation失敗
### Mutation reset
> ### reset會將error, data清空,mutation狀態將為Idle
```
const CreateTodo = () => {
const [title, setTitle] = useState('')
const mutation = useMutation({ mutationFn: createTodo })
const onCreateTodo = (e) => {
e.preventDefault()
mutation.mutate({ title })
}
return (
<form onSubmit={onCreateTodo}>
{mutation.error && (
<h5 onClick={() => mutation.reset()}>{mutation.error}</h5>
)}
<input
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<br />
<button type="submit">Create Todo</button>
</form>
)
}
```
### Mutation useIsMutating
> ### useIsMutating()可以取得mutating數量
> https://codesandbox.io/p/sandbox/react-query-shared-status-forked-593x7y?file=%2Fsrc%2FApp.tsx
```
function ComponentA() {
const { mutate } = useMutation(mutationFn, {
mutationKey: 'mutationKey'
});
const handleClick = () => {
mutate(); // invoke the mutation
}
return (/* ... */)
}
// get the mutation state from another component
function App() {
// the useIsMutating will return the number that is mutating
const isMutating = !!useIsMutating('mutationKey');
return (
<button disabled={isMutating}>Save</button>
)
}
```
### Side effect
```
useMutation({
mutationFn: addTodo,
//I will fire first
onSuccess: (data, variables, context) => {
// Trigger when mutation is successful
},
onError: (error, variables, context) => {
// Trigger when mutation is fail
},
onSettled: (data, error, variables, context) => {
// Trigger when mutation is successful or fail
},
})
mutate(todo, {
// I will fire second
onSuccess: (data, variables, context) => {
// ...
},
onError: (error, variables, context) => {
// ...
},
onSettled: (data, error, variables, context) => {
// ...
},
})
```
### Invalidate queries
> ### invalidateQueries()會將所有的query狀態標記為stale
```
// Invalidate every query in the cache
queryClient.invalidateQueries()
// Invalidate every query with a key that starts with `todos`
queryClient.invalidateQueries({
queryKey: ['todos'],
//Exactly match queryKey
exact: true,
})
// The query below will be invalidated
const todoListQuery = useQuery({
queryKey: ['todos'],
queryFn: fetchTodoList,
})
// However, the following query below will NOT be invalidated
const todoListQuery = useQuery({
queryKey: ['todos', { type: 'done' }],
queryFn: fetchTodoList,
})
import { useMutation, useQueryClient } from '@tanstack/react-query'
const queryClient = useQueryClient()
// When this mutation succeeds, invalidate any queries with the `todos` query key
const mutation = useMutation({
mutationFn: addTodo,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['todos'] })
},
})
```