UNPKG

react-usedrafty

Version:

๐Ÿ“ A React hook to auto-save and restore form state using localStorage or sessionStorage.

196 lines (145 loc) โ€ข 5.84 kB
# react-usedrafty React Drafty (๐Ÿ“„ `react-usedrafty`) is a plug-and-play hook for autosaving form state to localStorage or sessionStorage. No setup required. Restore drafts across page reloads โ€” for any form. ![npm](https://img.shields.io/npm/v/react-usedrafty) ![npm downloads](https://img.shields.io/npm/dt/react-usedrafty) ![license](https://img.shields.io/npm/l/react-usedrafty) ![issues](https://img.shields.io/github/issues/jsbimra/react-usedrafty) ![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg) --- ## ๐Ÿ”ฅ Features - โœ… Auto-save form state (localStorage/sessionStorage) - โœ… Zero-config usage - โœ… Restore values on mount - โœ… Works with controlled forms (React state) - โœ… TypeScript supported - โœ… Small, dependency-free - โœ… Warn user before leaving with unsaved changes (optional) - โœ… Custom debounce/save interval - โœ… Clean up/reset support - โœ… `onRestore` callback when draft is loaded - โœ… SPA navigation blocking (Next.js & React Router) if router object is provided --- ## ๐Ÿ“ฆ Installation ```bash npm install react-usedrafty # or yarn add react-usedrafty ``` --- ## ๐Ÿš€ Usage ### 1. Basic Example ```tsx import { useDrafty } from "react-usedrafty"; import { useState } from "react"; Variation 1 (Basic) function ContactForm() { const [formData, setFormData] = useState({ name: "", message: "" }); useDrafty("contact-form", formData, setFormData); return ( <form> <input value={formData.name} onChange={(e) => setFormData({ ...formData, name: e.target.value })} /> <textarea value={formData.message} onChange={(e) => setFormData({ ...formData, message: e.target.value })} /> </form> ); } Variation 2 (Advance) import { useDrafty } from "react-usedrafty"; function MyForm({ router }) { const [formState, setFormState] = useState({ name: "", email: "" }); const { saveDraft, clearDraft, hasDraft, isDirty } = useDrafty( "myForm", formState, setFormState, { debounce: 500, warnOnLeave: true, router } ); const handleSubmit = () => { // Send to API... clearDraft({ submitted: true }); // โœ… clears and prevents restoring stale data }; return ( <form onSubmit={handleSubmit}> {/* form fields */} </form> ); } ``` ### 2. Custom Options ```tsx useDrafty("draft-key", data, setData, { useSession: false, // Use sessionStorage instead of localStorage delay: 1500, // Autosave delay (ms) warnOnLeave: true, // Warn before leaving onRestore: (draft) => console.log("Restored draft:", draft), router: nextRouterInstance, // Optional: pass Next.js or React Router instance }); ``` --- ## ๐Ÿ“˜ API ### `useDrafty(key, state, setState, options?)` | Param | Type | Description | |--------------|-------------|-------------| | `key` | `string` | Storage key | | `state` | `object` | Your form state | | `setState` | `function` | State setter (e.g. `useState`) | | `options` | `object?` | Optional config | ### Options - `useSession`: Boolean โ€” Use `sessionStorage` instead of `localStorage` (default: false) - `debounce`: Number โ€” Debounce time in ms for saving drafts (defaults to 300ms if not provided; setting 0 still uses 300ms to avoid instant saves). - `warnOnLeave`: Boolean/String/Function โ€” Warn user before leaving with unsaved changes. (default: false) - `onRestore`: Function โ€” void โ€“ Callback when a draft is restored. - `router`: Object โ€” Optional Next.js or React Router instance to block SPA navigation ### Returns | Method | Type | Description | |--------|------|-------------| | `saveDraft()` | `() => void` | Saves current form state immediately. | | `clearDraft(options?: { submitted?: boolean })` | `() => void` | Clears the saved draft. If `submitted: true` is passed, sets a flag so the draft will not be restored next time the form is opened. | | `hasDraft` | `boolean` | Whether a saved draft exists. | | `isDirty` | `boolean` | Whether the current form state differs from the initially restored draft. | --- ## โœจ What's New - Added `onRestore` callback to run logic when draft is restored - Added `router` option for SPA navigation blocking in Next.js and React Router - Improved `warnOnLeave` to accept custom message or condition function - Debounce improvements for smoother autosave - Works with both localStorage and sessionStorage --- ## ๐Ÿ›  Troubleshooting If you face this error: ```ts Could not find a declaration file for module 'react'. ``` Install types for React: ```bash npm install --save-dev @types/react ``` --- ## ๐Ÿงช Example Directory A full working example (`/example`) with a contact form is included in the repo. Clone the repo and run locally to try it out! ```bash cd example npm install npm start ``` ## Changelog ### v2.1.0 **Enhancements** - **Improved debounce behavior** โ€” Draft is only saved after the user stops typing for the specified debounce period. No more instant save on first keystroke. - **Form submission awareness** โ€” New `clearDraft({ submitted: true })` option clears the draft and prevents restoring stale data when the form is reopened. - **Skip restore if submitted** โ€” If the form was submitted previously, old drafts are skipped to avoid overwriting updated backend data. - **Auto-clear on SPA navigation** โ€” If a router is passed (Next.js Pages Router or React Router), drafts are cleared when navigating away. - **State reset after submission** โ€” If the user edits the form again after submission, the submitted flag is removed and drafts are saved again. --- ## ๐Ÿ“„ License MIT --- ## โœ๏ธ Author Made by **jbviaai** with โค๏ธ Inspired by real-world use in feedback forms and checkout pages.