@cardql/react
Version:
CardQL SDK for React web applications with hooks and context providers
94 lines (80 loc) • 2.32 kB
text/typescript
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,
};
}