usePersistentState(value, storageKey, options): [value, setValue, purgeValue]
π‘π§ A React useState()
replacement with built-in persistence with Web Storage API. First-class TypeScript support πͺ
yarn add react-persistent-state-hook # or npm, pnpm, bun, etc.
// It works just like magic π
const [name, setName] = usePersistentState("John", "user-name")
// For more safety, provide a UNIQUE storageKey (strongly recommended πͺ)
const [name, setName] = usePersistentState("Billy", "ui/userAuth/name")
// For more versatility, use ENUMs as keys
const [name, setName] = usePersistentState("Tim", StorageKeys.USER_NAME)
Table of contents:
usePersistentState
adds persistence to React.useState
method:
-
π£ Plug'n'play with Minimal Configuration:
A simple replacement for
React.useState
hook - provide a unique key and you're good to go! -
π§ Data Persistence:
Store state values in
localStorage
orsessionStorage
. Until version 2, we only support Web Storage API, but more are coming. -
β»οΈ Platform-Agnostic:
usePersistentState
gracefully handles scenarios where Web Storage is not available, behaving exactly likeReact.useState
. -
π No Dependencies:
Keep your project light - no dependencies and a single peer dependency (
react >= 16.8
). -
π§βπ» First-class TypeScript Support:
Fully typed with TypeScript! π
-
π§ Roadmap for Continuous Improvement:
- The roadmap outlines upcoming features and enhancements, ensuring your state management needs are met.
-
π Documentation and Tutorials:
Straight-forward readme with examples and comprehensive JSDoc annotations for the hook and its options.
RPSH is committed to delivering a minimal and flexible solution for state management and persistence in React applications. Join me on this journey by contributing! π
Start by importing the hook:
import { usePersistentState } from "react-persistent-state-hook"
// Replace React.useState without breaking functionality - uses `localStorage`
const [count, setCount] = usePersistentState(0, "count")
const [count, setCount] = usePersistentState(() => 0, "count")
// Easy switching between local and session storages
const [count, setCount] = usePersistentState(0, "unique-key", "local")
const [count, setCount] = usePersistentState(0, "unique-key", "session")
// Configurable with options API
const [count, setCount] = usePersistentState(0, "unique-key", { verbose: true, persistent: false })
π‘ Possible state management replacement (like context or Redux) with zero configuration in situations where data loss is acceptable (like UI preferences). βοΈ
// You can use prefixes to group related keys
const [count, setCount] = usePersistentState(0, { prefix: "homepage", storageKey: "count" })
π‘ You can create a custom usePersistentState
hook with default options easily to share or persist configuration values across your application or different contexts:
import { createPersistentStateHook } from "react-persistent-state-hook"
// Create your own hook with defaults
export const useMyPersistentState = createPersistentStateHook({
storageType: "session",
prefix: "homepage/pagination",
})
// Usage - you can still override default options
const [page, setPage] = useMyPersistentState(1, { storageKey: "page" })
The Options API in react-persistent-state-hook
allows you to tweak the behavior of the hook. More configuration options are coming soon in minor releases.
Breaking changes in the Options API or elsewhere in react-persistent-state-hook
are only released in major versions π€
type Options = {
/** Print all warnings and errors in console. Overrides `silent` option.
* @default false */
verbose: boolean
/** The type of Web Storage API to use (either "session" or "local").
* @default "local" */
storageType: StorageType
/** Allow programatically enabling and disabling persistence in-place.
* @default true */
persistent: boolean
/** Allow the use of custom key prefix - group contexts or invalidate state version.
* @default "[rpsh]" */
prefix: string
}
- Resolution Strategies ?
- Add option to always override with new value, prefer stored value, or use stored if new value is
undefined
(default)
- Add option to always override with new value, prefer stored value, or use stored if new value is
- 1.0.0 Release π
- Freeze the
main
branch and move development todev-v1.x
branches, that eventually get merged intomain
as PRs. We need to act responsible π¨βπ«
- Freeze the
- More Storage Types
- Add support for
IndexedDB
,AsyncStorage
(React Native), URL params, cookies, etc.
- Add support for
- Even Smaller Footprint
- Reduce bundle size as much as possible
- Custom Serialization and Deserialization Methods
- Add the ability to configure your own serialization and deserialization functions instead of relying on
JSON.stringify
andJSON.parse
- for example to supportDate
and custom objects
- Add the ability to configure your own serialization and deserialization functions instead of relying on
- Open-source Friendliness
- Add a
CONTRIBUTING.md
file to make it easier for contributors to get started, link to it fromREADME.md
- Provide a solid tutorial for contributors, set up PR template, issue template, etc.
- Add a
- Storage Adapters API
- Say goodbye to Web Storage API as a core feature and say hello to storage adapters API. More flexibility, more possibilities! π
- Implement Web Storage and in-memory storage as exported storage adapter functions / objects
Start a new issue whenever you have any questions, problems or suggestions! Or feel free to open a pull request if you want to contribute. To increase the speed of getting your PR merged, please open an issue first to discuss your idea.
More info coming soon.