UNPKG

@cardql/react

Version:

CardQL SDK for React web applications with hooks and context providers

94 lines (80 loc) 2.32 kB
import { useState, useCallback } from "react"; import { useCardQLClient } from "../context"; export interface UseMutationOptions<TData = any, TVariables = any> { onSuccess?: (data: TData, variables: TVariables) => void; onError?: (error: any, variables: TVariables) => void; onSettled?: ( data: TData | undefined, error: any, variables: TVariables ) => void; } export interface UseMutationResult<TData = any, TVariables = any> { data: TData | undefined; loading: boolean; error: any; mutate: (variables: TVariables) => Promise<TData>; mutateAsync: (variables: TVariables) => Promise<TData>; reset: () => void; } /** * Hook for executing GraphQL mutations with CardQL */ export function useMutation<TData = any, TVariables = any>( mutation: string, options: UseMutationOptions<TData, TVariables> = {} ): UseMutationResult<TData, TVariables> { const cardql = useCardQLClient(); const [data, setData] = useState<TData | undefined>(undefined); const [loading, setLoading] = useState(false); const [error, setError] = useState<any>(null); const { onSuccess, onError, onSettled } = options; const mutateAsync = useCallback( async (variables: TVariables): Promise<TData> => { setLoading(true); setError(null); try { const result = await cardql.client.requestWithRetry<TData>( mutation, variables ); setData(result); setLoading(false); onSuccess?.(result, variables); onSettled?.(result, null, variables); return result; } catch (err) { setError(err); setLoading(false); onError?.(err, variables); onSettled?.(undefined, err, variables); throw err; } }, [cardql, mutation, onSuccess, onError, onSettled] ); const mutate = useCallback( async (variables: TVariables): Promise<TData> => { try { return await mutateAsync(variables); } catch (err) { // Error is already handled in mutateAsync return Promise.reject(err); } }, [mutateAsync] ); const reset = useCallback(() => { setData(undefined); setError(null); setLoading(false); }, []); return { data, loading, error, mutate, mutateAsync, reset, }; }