use-form-auto-save
Version:
A customizable React hook for automatically saving and restoring form data with support for localStorage, sessionStorage, and external APIs.
80 lines (79 loc) • 4.03 kB
TypeScript
/**
* This file contains the `useFormAutoSave` hook, a custom React hook for automatically saving form data.
* It supports localStorage, sessionStorage, and API-based saving with features like debouncing, retries, and error handling.
*
* Related utilities:
* - `useSaveHandler`: Handles the save logic.
* - `useRetryHandler`: Manages retry logic for failed saves.
*/
import { AutoSaveConfig } from './types';
/**
* useFormAutoSave - Custom React Hook for automatically saving form data.
*
* This hook provides an efficient and customizable solution to automatically save form data
* to either localStorage, sessionStorage, or an external API, based on your preference.
* It supports debouncing, error handling, automatic retry mechanisms, and form restoration.
*
* @param {AutoSaveConfig} config - Configuration object to customize hook behavior.
*
* @property {string} config.formKey - A unique key identifying the form data for storage/retrieval.
* @property {object} [config.formData] - Form data object (use when manually handling form state).
* @property {Control<any>} [config.control] - React Hook Form control object (use with React Hook Form).
* @property {number} [config.debounceTime=1000] - Delay in milliseconds before auto-save triggers after changes.
* @property {"localStorage"|"sessionStorage"|"api"} [config.storageType="localStorage"] - Storage medium.
* @property {SaveFunction} [config.saveFunction] - Custom asynchronous function for API-based saving.
* @property {ErrorCallback} [config.onError] - Callback triggered on save error.
* @property {number} [config.maxRetries=3] - Number of retry attempts on failure before pausing auto-save.
* @property {boolean} [config.skipInitialSave=false] - Skip auto-saving on initial render.
* @property {boolean} [config.debug=false] - Enable debug logging for the hook.
*
* @returns {object} Object containing methods and state for managing auto-save functionality:
* - restoreFormData(): Function to retrieve saved form data (null if using API storage).
* - resumeAutoSave(): Function to manually resume auto-save if paused after retries.
* - isSaving: Indicates if auto-save is currently in progress.
* - isSaveSuccessful: Indicates if the last auto-save operation was successful.
* - isAutoSavePaused: Indicates if auto-save is paused due to consecutive errors.
* - setLastSavedData: Function to manually update the internally tracked last saved data. Useful for syncing the last saved state manually.
*
* @example
* // Basic usage with localStorage
* const { restoreFormData, isSaving } = useFormAutoSave({
* formKey: 'userForm',
* formData: formState,
* });
*
* @example
* // Advanced usage with API storage and error handling
* const { isSaveSuccessful, resumeAutoSave } = useFormAutoSave({
* formKey: 'userProfile',
* control,
* storageType: 'api',
* debounceTime: 2000,
* saveFunction: async (data) => await apiClient.saveUserProfile(data),
* onError: (err) => toast.error("Auto-save failed."),
* maxRetries: 5,
* });
*
* @note
* - When using 'api' storage type, you must provide a `saveFunction`.
* - `restoreFormData` is not available when using 'api' storage type.
* - The hook automatically pauses auto-save after exhausting retries; use `resumeAutoSave` to restart.
*
* - Auto-save is skipped under the following conditions:
* - watchedFormState or formKey is missing.
* - Auto-save is paused due to consecutive errors.
* - The form state is empty.
* - The initial save is skipped (skipInitialSave is true).
* - The form data has not changed since the last save.
*
* @author Damyant Jain (https://github.com/damyantjain)
* @license MIT
*/
export declare const useFormAutoSave: (config: AutoSaveConfig) => {
restoreFormData: () => any;
isSaving: boolean;
isSaveSuccessful: boolean;
isAutoSavePaused: boolean;
resumeAutoSave: () => void;
setLastSavedData: import("react").Dispatch<import("react").SetStateAction<object | null>>;
};