use-persisted-state-hook
DefinitelyTyped icon, indicating that this package has TypeScript declarations provided by the separate @types/use-persisted-state-hook package

1.4.0 • Public • Published

npm version

Lightweight, resilient persisted useState.

Features:

  • 📦 Persist state on localStorage between browser sessions.
  • ⚛️ Automatically handle state's shape updates.
  • 🔄 Handle stale states when initial state changes.
  • Similar interface to React's official useState hook.
  • Server Side Render Support.

Installation

npm:

npm install use-persisted-state-hook

yarn:

yarn add use-persisted-state-hook

Detect Changes in Initial State

use-persisted-state-hook is the only library that handles changes in initial state gracefully. Leet's imagine that you have a hook called useLocalStorage like the one provided here. It has the same API that useState and looks like this:

function Greet() {
  const [visits, setVisits] = useLocalStorage('visits', 0)

  // Logic to update visits...

  return (
    <div>Visits count is {visits}</div>
  )
}

Now, imagine that you want to update the initial state to it stores more information:

function Greet() {
  const [visits, setVisits] = useLocalStorage('visits', { today: 0, total: 0 }))

  // Logic to update visits...

  return (
    <div>
      <div>Today's count is {visits.today}</div>
      <div>Total count is {visits.total}</div>
    </div>
  )
}

The code above works, however, there's a pitfall. A user that loaded your app after you released the first version, so the value it has stored for visits is 0 (or 1, or 5, or any integer). When they load your app again with the new logic, they'll see "Today's count is " and "Total count is ".

usePersistedState is the only library that handles this case gracefully by storing an identifier that identifies uniquely the initial state so, whenever it changes, the state it's going to be reset and you'd never have to think about this issue in the first place

Usage

Simple Example

import React from 'react'
import usePersistedState from 'use-persisted-state-hook'

function Counter() {
  const [count, setCount] = usePersistedState('count', 0)

  return (
    <div>
      <div>Count is {count}</div>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <button onClick={() => setCount(count - 1)}>Decrement</button>
    </div>
  )
}

export default Counter

Elaborated Example

Expected output

Code (styles ommited):

import React from 'react'
import usePersistedState from 'use-persisted-state-hook'

function Settings() {
  const [options, setOptions] = usePersistedState('options', [
    { title: 'Dark Mode', name: 'dark_mode', enabled: true },
    { title: 'Data Saving 2', name: 'data_saving', enabled: true },
  ])

  const onClick = (e) => {
    setOptions(
      options.map((option) =>
        option.name === e.target.name
          ? { ...option, enabled: !option.enabled }
          : option
      )
    )
  }

  return (
    <div>
      {options.map((option) => (
        <label>
          <input
            type="checkbox"
            name={option.name}
            checked={option.enabled}
            onClick={onClick}
          />{' '}
          {option.title}
        </label>
      ))}
    </div>
  )
}

Readme

Keywords

none

Package Sidebar

Install

npm i use-persisted-state-hook

Weekly Downloads

687

Version

1.4.0

License

MIT

Unpacked Size

19.4 kB

Total Files

12

Last publish

Collaborators

  • giovannibenussi