| 189 | * ``` |
| 190 | */ |
| 191 | export function useMutation< |
| 192 | TData = unknown, |
| 193 | TError = DefaultError, |
| 194 | TVariables = void, |
| 195 | TOnMutateResult = unknown, |
| 196 | >( |
| 197 | options: UseMutationOptions<TData, TError, TVariables, TOnMutateResult>, |
| 198 | queryClient?: QueryClient, |
| 199 | ): UseMutationResult<TData, TError, TVariables, TOnMutateResult> { |
| 200 | const client = useQueryClient(queryClient) |
| 201 | |
| 202 | const [observer] = React.useState( |
| 203 | () => |
| 204 | new MutationObserver<TData, TError, TVariables, TOnMutateResult>( |
| 205 | client, |
| 206 | options, |
| 207 | ), |
| 208 | ) |
| 209 | |
| 210 | React.useEffect(() => { |
| 211 | observer.setOptions(options) |
| 212 | }, [observer, options]) |
| 213 | |
| 214 | const result = React.useSyncExternalStore( |
| 215 | React.useCallback( |
| 216 | (onStoreChange) => |
| 217 | observer.subscribe(notifyManager.batchCalls(onStoreChange)), |
| 218 | [observer], |
| 219 | ), |
| 220 | () => observer.getCurrentResult(), |
| 221 | () => observer.getCurrentResult(), |
| 222 | ) |
| 223 | |
| 224 | const mutate = React.useCallback< |
| 225 | UseMutateFunction<TData, TError, TVariables, TOnMutateResult> |
| 226 | >( |
| 227 | ( |
| 228 | ...args: Parameters< |
| 229 | UseMutateFunction<TData, TError, TVariables, TOnMutateResult> |
| 230 | > |
| 231 | ) => { |
| 232 | observer.mutate(args[0] as TVariables, args[1]).catch(noop) |
| 233 | }, |
| 234 | [observer], |
| 235 | ) |
| 236 | |
| 237 | if ( |
| 238 | result.error && |
| 239 | shouldThrowError(observer.options.throwOnError, [result.error]) |
| 240 | ) { |
| 241 | throw result.error |
| 242 | } |
| 243 | |
| 244 | return { ...result, mutate, mutateAsync: result.mutate } |
| 245 | } |