UNPKG

@supunlakmal/hooks

Version:

A collection of reusable React hooks

68 lines 3.03 kB
import { useState, useCallback, useRef, useEffect } from 'react'; /** * Hook to manage asynchronous operations that modify data (mutations). * Handles loading, success, and error states, and provides callbacks. * * @param mutationFn The asynchronous function that performs the mutation. * @param options Optional configuration with callbacks (onSuccess, onError, etc.). * @returns State and functions to manage the mutation lifecycle. */ export const useMutation = (mutationFn, options) => { const [status, setStatus] = useState('idle'); const [data, setData] = useState(undefined); const [error, setError] = useState(undefined); // Use refs for callbacks to avoid including them in the mutate callback dependencies const optionsRef = useRef(options); const mutationFnRef = useRef(mutationFn); // Update refs if options change useEffect(() => { optionsRef.current = options; }, [options]); useEffect(() => { mutationFnRef.current = mutationFn; }, [mutationFn]); const reset = useCallback(() => { setStatus('idle'); setData(undefined); setError(undefined); }, []); const mutateAsync = useCallback(async (variables) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; setStatus('loading'); setData(undefined); setError(undefined); (_b = (_a = optionsRef.current) === null || _a === void 0 ? void 0 : _a.onMutate) === null || _b === void 0 ? void 0 : _b.call(_a, variables); try { const result = await mutationFnRef.current(variables); setData(result); setStatus('success'); (_d = (_c = optionsRef.current) === null || _c === void 0 ? void 0 : _c.onSuccess) === null || _d === void 0 ? void 0 : _d.call(_c, result, variables); (_f = (_e = optionsRef.current) === null || _e === void 0 ? void 0 : _e.onSettled) === null || _f === void 0 ? void 0 : _f.call(_e, result, undefined, variables); return result; } catch (err) { setError(err); setStatus('error'); (_h = (_g = optionsRef.current) === null || _g === void 0 ? void 0 : _g.onError) === null || _h === void 0 ? void 0 : _h.call(_g, err, variables); (_k = (_j = optionsRef.current) === null || _j === void 0 ? void 0 : _j.onSettled) === null || _k === void 0 ? void 0 : _k.call(_j, undefined, err, variables); // Rethrow the error so callers of mutateAsync can catch it if needed throw err; } }, []); // No dependencies needed due to refs const mutate = useCallback((variables) => { return mutateAsync(variables); }, [mutateAsync]); return { status, data, error, isLoading: status === 'loading', isSuccess: status === 'success', isError: status === 'error', isIdle: status === 'idle', mutate, mutateAsync, reset, }; }; //# sourceMappingURL=useMutation.js.map