Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 5x 2x 2x 2x 3x 8x 8x | import { useFormikContext, type FormikErrors, type FormikValues } from 'formik';
import { isEqual } from 'lodash-es';
import { useEffect, useRef } from 'react';
export type UseFormikAutosaveOptions<TValues extends FormikValues = FormikValues> = {
/** Called with the current values. */
onSave: (values: TValues, errors: FormikErrors<TValues>) => void;
/** Time to wait when the values change before calling onSave. */
timeoutMs?: number;
};
export const useFormikAutosave = <TValues extends FormikValues = FormikValues>({
onSave,
timeoutMs = 1000,
}: UseFormikAutosaveOptions<TValues>) => {
// Keep a ref on the onSave function, so it does not reset the timeout if the function reference is unstable.
const onSaveRef = useRef(onSave);
onSaveRef.current = onSave;
// Subscribe to values change.
const { values, errors, initialValues, isSubmitting } = useFormikContext<TValues>();
// When the values change, call the onSave function after timeoutMs.
// Reset the timeout if values change again before timeoutMs expires.
useEffect(() => {
if (!isSubmitting && !isEqual(values, initialValues)) {
const timeoutHandle = setTimeout(() => onSaveRef.current(values, errors), timeoutMs);
return () => clearTimeout(timeoutHandle);
}
return undefined;
}, [initialValues, values, errors, timeoutMs, isSubmitting]);
};
|