Skip to content

guoyunhe/react-storage

Repository files navigation

@guoyunhe/react-storage

npm downloads minzipped size

Better useLocalStorage() and useSessionStorage() hooks.

Installation

npm install --save @guoyunhe/react-storage

Examples

Simple

By default, useLocalStorage support JSON data.

import { useLocalStorage, useSessionStorage } from '@guoyunhe/react-storage';

interface Settings {
  color: string;
  size: number;
}

function App() {
  const [settings, setSettings] = useLocalStorage<Settings>('settings', { color: 'red', size: 20 });
  const [draft, setDraft] = useSessionStorage<string>('draft', '');
}

Customize serializer and parser

You can use options to customize serializer and parser.

import { useLocalStorage } from '@guoyunhe/react-storage';

function App() {
  const [date, setDate] = useLocalStorage('date', new Date(), {
    serializer: (date) => date.toISOString(),
    parser: (str) => new Date(str),
  });
}

Storage key prefix

LocalStorage is scoped by domain. However, you may have multiple React apps under same domain and don't want to share data between. In this case, you can specify a global prefix with <StorageProvider/>.

import { useLocalStorage, StorageProvider } from '@guoyunhe/react-storage';

function App() {
  return (
    <StorageProvider prefix="dashboard_">
      <Page />
    </StorageProvider>
  );
}

function Page() {
  // The actual storage key will be `dashboard_dark_mode`
  const [darkMode, setDarkMode] = useLocalStorage('dark_mode', false);
}

Sync state across components and browser tabs

Communicating through stroage event, states can sync between different components and browser tabs, in real-time, without extra effort.

import { useLocalStorage, StorageProvider } from '@guoyunhe/react-storage';

function Page() {
  const [count, setCount] = useLocalStorage('count', 0);
  return (
    <div style={{ background: '#8888', padding: 4 }}>
      <button onClick={() => setCount((prev) => prev - 1)}>-</button>
      <span style={{ paddingInline: 8 }}>{count}</span>
      <button onClick={() => setCount((prev) => prev + 1)}>+</button>
    </div>
  );
}

render(
  <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'start', gap: 8 }}>
    <Page />
    <Page />
  </div>,
);

API

useLocalStorage(key, defaultValue, options)

useLocalStorage() can not only persist data, but also share state between browser tabs!

Remember that localStorage has a 5MB size limit. Do NOT write too many data into it.

key

Type: string

Storage key. If prefix is defined, actual storage key is prefix + key.

defaultValue

Type: T

Default value to use when storage doesn't exist or can not be parsed.

options.serializer

Type: (value: T) => string

Default: JSON.stringify

Serialize value to string.

options.parser

Type: (data: string) => T

Default: JSON.parse

Parse string to value.

options.prefix

Type: string

In case you defined global prefix in <StorageProvider/>, but need to override it in some places.

useSessionStorage()

API is the same as useLocalStorage(), but store data in sessionStorage, which will be clear after closing browser tabs. It is useful when you want an easy way to:

  • Share state between different React components or apps in the same browser tab
  • Remember state after refreshing browser tab

Remember that sessionStorage also has a 5MB size limit. Do NOT write too many data into it.

StorageProvider

Define global configuration for hooks.

prefix

Type: string

If prefix is defined, actual storage key is prefix + key.

serializer

Type: (value: T) => string

Default: JSON.stringify

Serialize value to string.

parser

Type: (data: string) => T

Default: JSON.parse

Parse string to value.

Comparison

Package TS ESM Prefix Sync across tabs Sync across components Bundle size
@guoyunhe/react-storage Bundle size
use-local-storage-state Bundle size
use-local-storage Bundle size
react-storage-hooks Bundle size
react-use Bundle size
ahooks Bundle size