{"id":15483762,"url":"https://github.com/leoafarias/use-state-persist","last_synced_at":"2025-10-11T18:09:30.099Z","repository":{"id":46172797,"uuid":"266423681","full_name":"leoafarias/use-state-persist","owner":"leoafarias","description":"Simple React Hook to persist/cache the useState locally. Easily load stale state for better ux.","archived":false,"fork":false,"pushed_at":"2022-07-18T13:11:11.000Z","size":430,"stargazers_count":53,"open_issues_count":8,"forks_count":5,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-22T16:55:48.878Z","etag":null,"topics":["asyncstorage","hooks","localstorage","persistent","react-hooks","usestate"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leoafarias.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-23T21:37:47.000Z","updated_at":"2025-02-18T09:33:08.000Z","dependencies_parsed_at":"2022-09-24T21:21:19.062Z","dependency_job_id":null,"html_url":"https://github.com/leoafarias/use-state-persist","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/leoafarias/use-state-persist","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leoafarias%2Fuse-state-persist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leoafarias%2Fuse-state-persist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leoafarias%2Fuse-state-persist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leoafarias%2Fuse-state-persist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leoafarias","download_url":"https://codeload.github.com/leoafarias/use-state-persist/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leoafarias%2Fuse-state-persist/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279008299,"owners_count":26084428,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asyncstorage","hooks","localstorage","persistent","react-hooks","usestate"],"created_at":"2024-10-02T05:20:40.685Z","updated_at":"2025-10-11T18:09:30.065Z","avatar_url":"https://github.com/leoafarias.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Use State Persist\n\n![CI](https://github.com/leoafarias/use-state-persist/workflows/CI/badge.svg?branch=master) [![Coverage Status](https://coveralls.io/repos/github/leoafarias/use-state-persist/badge.svg?branch=master)](https://coveralls.io/github/leoafarias/use-state-persist?branch=master) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/9b1c2ea8d9c84c2bb37a49b2adce88a5)](https://app.codacy.com/manual/leo/use-state-persist?utm_source=github.com\u0026utm_medium=referral\u0026utm_content=leoafarias/use-state-persist\u0026utm_campaign=Badge_Grade_Dashboard) [![npm version](https://badgen.net/npm/v/use-state-persist)](https://www.npmjs.com/package/use-state-persist)\n\nA simple React Hook to persist **useState** in local storage.\n\nWorks on the `Web` and `React Native`.\n\n**Easily implement**\n\n- Offline state\n- Stale while revalidate flow\n- Global state\n\n```bash\nnpm install use-state-persist\n# or\nyarn add use-state-persist\n```\n\nFor `React Native` make sure you do the following on app start up:\n\n```typescript\nimport { syncStorage } from 'use-state-persist';\n\n// Initialize async storage\nawait syncStorage.init();\n```\n\n## How to persists useState\n\nSame behavior and API as `useState` so you can use it by easily replacing the `useState` hook for the calls which you want to persist offline.\n\n```tsx\nimport { useStatePersist as useState } from 'use-state-persist';\n\nconst Component = () =\u003e {\n  // Before\n  //const [counter, setCounter] = useState(0);\n  const [counter, setCounter] = useState('@counter', 0);\n\n  return \u003cCounterDisplay value={counter} /\u003e;\n};\n```\n\n## Stale While Revalidate\n\n```tsx\nimport { useStatePersist as useState } from 'use-state-persist';\n\nconst Component = () =\u003e {\n  // Loads stale state\n  const [data, setData] = useState('@data');\n\n  const fetchData = async () =\u003e {\n    // Fetches new state\n    const data = await fetch('/endpoint');\n    setData(data);\n  };\n\n  useEffect(() =\u003e {\n    fetchData();\n  }, []);\n\n  return \u003cDataDisplay value={data} /\u003e;\n};\n```\n\n## Global State\n\nSimple event system allows all the storage writes to be dispatched to all hooks . That means that all `useStatePersist()` can be used as a global state by sharing the same key `useStatePersist('@globalKey')`\n\nTo avoid that just make sure that the key being passed to the hook is unique `useStatePersist('@uniqueKey')`\n\n```tsx\nconst CounterButton = () =\u003e {\n  const [counter, setCounter] = useState('@counter');\n\n  return \u003cButton onClick={() =\u003e setCounter(counter =\u003e counter++)} /\u003e;\n};\n```\n\nState will be updated across multiple components\n\n```tsx\nconst ShowCounter = () =\u003e {\n  const [counter, setCounter] = useState('@counter', 0);\n\n  return \u003cCounterDisplay value={counter} /\u003e;\n};\n```\n\n## Cache Invalidation\n\nThere are some cases where you might want to clear all the local storage cache for the hook, pending a certain change in state in the app.\n\nThis will clear all the local storage items use by the `useStatePersist` hook when the key changes.\n\n### Use Cases\n\n- User/App State changes\n- User Log out\n- Environment variable changes\n\n```tsx\nimport { invalidateCache } from 'use-state-persist';\n\ninvalidateCache('CACHE_KEY');\n\n// You can also send a promise which will compare the result\ninvalidateCache(async () =\u003e 'CACHE_KEY');\n```\n\n### React Native\n\nInit prepares the SyncStorage to work synchronously, by getting all values for all keys stored on AsyncStorage. You can use the init method on the web without any side effects to keep code consistency.\n\n```typescript\nimport { syncStorage } from 'use-state-persist';\n\nawait syncStorage.init();\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleoafarias%2Fuse-state-persist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleoafarias%2Fuse-state-persist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleoafarias%2Fuse-state-persist/lists"}