## 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'] }) }, }) ```