UNPKG

@preact-signals/query

Version:

A reactive utility for React/Preact that simplifies the handling of data fetching and state management. Powered by Preact Signals, it provides hooks and functions to create reactive resources and manage their state seamlessly.

127 lines (116 loc) 3.35 kB
'use client' import * as React from 'react' import { useSyncExternalStore } from './useSyncExternalStore.ts' import type { MutationFunction, MutationKey } from '@tanstack/query-core' import { notifyManager, parseMutationArgs, MutationObserver, } from '@tanstack/query-core' import { useQueryClient } from './QueryClientProvider.tsx' import type { UseMutateFunction, UseMutationOptions, UseMutationResult, } from './types.ts' import { shouldThrowError } from './utils.ts' // HOOK export function useMutation< TData = unknown, TError = unknown, TVariables = void, TContext = unknown, >( options: UseMutationOptions<TData, TError, TVariables, TContext>, ): UseMutationResult<TData, TError, TVariables, TContext> export function useMutation< TData = unknown, TError = unknown, TVariables = void, TContext = unknown, >( mutationFn: MutationFunction<TData, TVariables>, options?: Omit< UseMutationOptions<TData, TError, TVariables, TContext>, 'mutationFn' >, ): UseMutationResult<TData, TError, TVariables, TContext> export function useMutation< TData = unknown, TError = unknown, TVariables = void, TContext = unknown, >( mutationKey: MutationKey, options?: Omit< UseMutationOptions<TData, TError, TVariables, TContext>, 'mutationKey' >, ): UseMutationResult<TData, TError, TVariables, TContext> export function useMutation< TData = unknown, TError = unknown, TVariables = void, TContext = unknown, >( mutationKey: MutationKey, mutationFn?: MutationFunction<TData, TVariables>, options?: Omit< UseMutationOptions<TData, TError, TVariables, TContext>, 'mutationKey' | 'mutationFn' >, ): UseMutationResult<TData, TError, TVariables, TContext> export function useMutation< TData = unknown, TError = unknown, TVariables = void, TContext = unknown, >( arg1: | MutationKey | MutationFunction<TData, TVariables> | UseMutationOptions<TData, TError, TVariables, TContext>, arg2?: | MutationFunction<TData, TVariables> | UseMutationOptions<TData, TError, TVariables, TContext>, arg3?: UseMutationOptions<TData, TError, TVariables, TContext>, ): UseMutationResult<TData, TError, TVariables, TContext> { const options = parseMutationArgs(arg1, arg2, arg3) const queryClient = useQueryClient({ context: options.context }) const [observer] = React.useState( () => new MutationObserver<TData, TError, TVariables, TContext>( queryClient, options, ), ) React.useEffect(() => { observer.setOptions(options) }, [observer, options]) const result = useSyncExternalStore( React.useCallback( (onStoreChange) => observer.subscribe(notifyManager.batchCalls(onStoreChange)), [observer], ), () => observer.getCurrentResult(), () => observer.getCurrentResult(), ) const mutate = React.useCallback< UseMutateFunction<TData, TError, TVariables, TContext> >( (variables, mutateOptions) => { observer.mutate(variables, mutateOptions).catch(noop) }, [observer], ) if ( result.error && shouldThrowError(observer.options.useErrorBoundary, [result.error]) ) { throw result.error } return { ...result, mutate, mutateAsync: result.mutate } } // eslint-disable-next-line @typescript-eslint/no-empty-function function noop() {}