├── .editorconfig ├── .gitignore ├── README.md ├── index.d.ts ├── package.json ├── src └── index.ts ├── tsconfig.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # production 5 | index.js 6 | 7 | # misc 8 | .DS_Store 9 | .idea 10 | .env.local 11 | .env.development.local 12 | .env.test.local 13 | .env.production.local 14 | 15 | npm-debug.log* 16 | yarn-debug.log* 17 | yarn-error.log* 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Persist Hook 2 | 3 | Hook for persisting and rehydrating state in the React app. 4 | 5 | ## Installation 6 | 7 | ```bash 8 | npm install react-persist-hook 9 | ``` 10 | or 11 | ```bash 12 | yarn add react-persist-hook 13 | ``` 14 | 15 | ## Usage 16 | 17 | ```javascript 18 | import React from 'react' 19 | import usePersist from 'react-persist-hook' 20 | 21 | const Signin = () => { 22 | const [signinFormValues, setSigninFormValues] = usePersist('signin-form', 'localStorage', 400); 23 | 24 | const { userName, email } = signinFormValues || {}; 25 | const initValues = { userName, email }; 26 | 27 | const handleSubmit = ({ userName, email }) => { 28 | setSigninFormValues({ userName, email }); 29 | // rest of the submit method 30 | } 31 | 32 | return ( 33 |
34 | {/* rest of the code */} 35 |
36 | ) 37 | } 38 | ``` 39 | 40 | ## Props 41 | 42 | | Prop | Type | Default | Required | Description | 43 | |---------------|------------------------------------------|----------------|----------|-------------------------------------------------------| 44 | | key | string | | true | Unique storage key | 45 | | storageType | ['localStorage'|'sessionStorage'] | 'localStorage' | false | Storage type name | 46 | | debounceLimit | number | 250 | false | Time in milliseconds to debounce the state persisting | 47 | 48 | 49 | ## License 50 | [MIT](https://choosealicense.com/licenses/mit/) 51 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | declare const usePersist: (key: string, storageType?: "localStorage" | "sessionStorage" | undefined, debounceLimit?: number | undefined) => [any, Function]; 2 | export default usePersist; 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-persist-hook", 3 | "version": "1.0.7", 4 | "description": "Hook for persisting and rehydrating state in React app", 5 | "main": "index.js", 6 | "types": "index.d.ts", 7 | "scripts": { 8 | "build": "tsc && echo 'Finished building NPM package'", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/szlezak/react-persist-hook.git" 14 | }, 15 | "keywords": [ 16 | "react", 17 | "react-hook", 18 | "persist" 19 | ], 20 | "author": { 21 | "name": "Robert Szlezak", 22 | "email": "robertszlezak@gmail.com" 23 | }, 24 | "contributors": [ 25 | { 26 | "name": "Mark Polak", 27 | "email": "mwd@outlook.sk" 28 | } 29 | ], 30 | "license": "MIT", 31 | "bugs": { 32 | "url": "https://github.com/szlezak/react-persist-hook/issues" 33 | }, 34 | "homepage": "https://github.com/szlezak/react-persist-hook#readme", 35 | "peerDependencies": { 36 | "react": "^16.0.0-0" 37 | }, 38 | "devDependencies": { 39 | "typescript": "^3.6.4", 40 | "@types/react": "^16.9.9", 41 | "@types/lodash.debounce": "^4.0.6" 42 | }, 43 | "dependencies": { 44 | "lodash.debounce": "^4.0.8" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, useState } from 'react'; 2 | import debounce from 'lodash.debounce'; 3 | 4 | const usePersist = ( 5 | key: string, 6 | storageType?: 'localStorage' | 'sessionStorage', 7 | debounceLimit?: number, 8 | ): [any, Function] => { 9 | const DEBOUNCE_LIMIT = debounceLimit || 250; 10 | const STORAGE_TYPE = storageType || 'localStorage'; 11 | 12 | const mounted = useRef(); 13 | const [data, setData] = useState({}); 14 | 15 | const persist = debounce(dataToStore => { 16 | window[STORAGE_TYPE].setItem(key, JSON.stringify(dataToStore)); 17 | }, DEBOUNCE_LIMIT); 18 | 19 | useEffect(() => { 20 | if (!mounted.current) { 21 | const storedData = window[STORAGE_TYPE].getItem(key); 22 | 23 | mounted.current = true; 24 | storedData && setData(JSON.parse(storedData)); 25 | } else { 26 | persist(data); 27 | } 28 | }, [data]); 29 | 30 | return [data, setData]; 31 | }; 32 | 33 | export default usePersist; 34 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "outDir": ".", 7 | "strict": true, 8 | "moduleResolution": "node", 9 | "allowSyntheticDefaultImports": true, 10 | "esModuleInterop": true, 11 | "experimentalDecorators": true, 12 | "declaration": true 13 | }, 14 | "exclude": ["node_modules", "index.d.ts"] 15 | } 16 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@types/lodash.debounce@^4.0.6": 6 | version "4.0.6" 7 | resolved "https://registry.yarnpkg.com/@types/lodash.debounce/-/lodash.debounce-4.0.6.tgz#c5a2326cd3efc46566c47e4c0aa248dc0ee57d60" 8 | integrity sha512-4WTmnnhCfDvvuLMaF3KV4Qfki93KebocUF45msxhYyjMttZDQYzHkO639ohhk8+oco2cluAFL3t5+Jn4mleylQ== 9 | dependencies: 10 | "@types/lodash" "*" 11 | 12 | "@types/lodash@*": 13 | version "4.14.144" 14 | resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.144.tgz#12e57fc99064bce45e5ab3c8bc4783feb75eab8e" 15 | integrity sha512-ogI4g9W5qIQQUhXAclq6zhqgqNUr7UlFaqDHbch7WLSLeeM/7d3CRaw7GLajxvyFvhJqw4Rpcz5bhoaYtIx6Tg== 16 | 17 | "@types/prop-types@*": 18 | version "15.7.3" 19 | resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" 20 | integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== 21 | 22 | "@types/react@^16.9.9": 23 | version "16.9.9" 24 | resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.9.tgz#a62c6f40f04bc7681be5e20975503a64fe783c3a" 25 | integrity sha512-L+AudFJkDukk+ukInYvpoAPyJK5q1GanFOINOJnM0w6tUgITuWvJ4jyoBPFL7z4/L8hGLd+K/6xR5uUjXu0vVg== 26 | dependencies: 27 | "@types/prop-types" "*" 28 | csstype "^2.2.0" 29 | 30 | csstype@^2.2.0: 31 | version "2.6.7" 32 | resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.7.tgz#20b0024c20b6718f4eda3853a1f5a1cce7f5e4a5" 33 | integrity sha512-9Mcn9sFbGBAdmimWb2gLVDtFJzeKtDGIr76TUqmjZrw9LFXBMSU70lcs+C0/7fyCd6iBDqmksUcCOUIkisPHsQ== 34 | 35 | lodash.debounce@^4.0.8: 36 | version "4.0.8" 37 | resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" 38 | integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= 39 | 40 | typescript@^3.6.4: 41 | version "3.6.4" 42 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.4.tgz#b18752bb3792bc1a0281335f7f6ebf1bbfc5b91d" 43 | integrity sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg== 44 | --------------------------------------------------------------------------------