Introduction to a stateful & maintainable React Local Storage hook

When it comes to storing a value on the client-side persistently, most of us will prefer browser storage (local or session storage) because of its simplified APIs to store and retrieve data.

Yet maintaining these storages in large-scale applications are not so easy, especially with micro frontends architecture.

The hook @webcored/react-local-storage provides an awesome set of features to maintain the browser storage effortlessly for the long run.

Namespacing & Configurations

Unless it's documented, we don't know the storage keys being used in an application & we are not sure about the values of the keys as well.

Key name conflicts are more common in micro-frontends. An app should control its own set of keys and it should not override the common or other app's key. Hence, namespacing plays a major factor to avoid these conflicts.

import { storageConfig } from "@webcored/react-local-storage";

storageConfig({
  namespace: 'dev',
  delimiter: '#',
})

If the key is user, the storage key name is dev#user.

other available storage configurations,

  • storage: choose between local or session storage
  • storages: key configurations
  • react: instance for state management (useState hook)
import react from 'react';
import { user } from './storages/user';

import { storageConfig } from "@webcored/react-local-storage";

storageConfig({
  namespace: 'dev',
  delimiter: '#',
  storage: window.sessionStorage,
  storages: {
   user // user key configs
  },
  react,
})

Defaults & States

The default state for keys in browser storage is the most required feature. It indulges a lot of programming effort to maintain the default state for every key.

In @webcored/react-local-storage each key can have its config, and the default states for keys can be incorporated easily.

/storages/user.js

import { storageKeyConfig } from "@webcored/react-local-storage"

const user = storageKeyConfig({
  defaults: {
    name: 'Guest',
    email: '[email protected]'
  }
})

The storages are simply accessible via the useLocalStorage hook in a stateful way.

/component.js

import { useLocalStorage } from "@webcored/react-local-storage";

const [user, userStorage] = useLocalStorage('user');

And the dispatcher comes with painless APIs to invoke the storage programmatically.

update

userStorage.update({ ...user, avatar: 'avatar.jpg' });

reset

Reset the storage to the default state.

userStorage.reset();

remove

userStorage.remove();

Versions & Migrations

Since the storages are persistent, changing its data structure quite often may be challenging, and it involves a lot of code changes per key. With @webcored/react-local-storage these data migrations can be simply handled with a version number & a migration callback in the key config.

import { storageKeyConfig } from "@webcored/react-local-storage"

const user = storageKeyConfig({
  defaults: {
    name: 'Guest',
    email: '[email protected]',
    avatar: 'guest.png' // new
  },
  version: 2,
  migration: (currentValue, defaultValue) {
    return Object.assign({}, ...currentValue, ...defaultValue);
  }
})

@webcored/react-local-storage supports versioning of keys by default.
As per the above code block, the current version of user storage is incremented. While rendering, if the browser had an outdated version of storage, the migration method will be invoked. The migrated value will be considered as the latest version.

other highlights

  • supports all data types
  • typescript supported

checkout the sample apps

If you like, Promote the lib with a star ⭐️

GitHub logo webcored / react-local-storage

A stateful react hook for browser storage

React Local Storage

A stateful react hook for browser storage.

build npm downloads typescript contributions

Why?

Install

npm install @webcored/react-local-storage

Usage

component.jsx

import { useLocalStorage } from "@webcored/react-local-storage";
const [user, userStorage] = useLocalStorage('user');

....
Enter fullscreen mode Exit fullscreen mode
typescript
const [user, userStorage] = useLocalStorage<User>('user');
  
....
Enter fullscreen mode Exit fullscreen mode
update
userStorage.update({ ...user, name: 'new name' });
Enter fullscreen mode Exit fullscreen mode
remove
userStorage.remove();
Enter fullscreen mode Exit fullscreen mode
reset

Reset's to the default value provided in the key config

userStorage.reset();
Enter fullscreen mode Exit fullscreen mode

Sample app

typescript

Configurations

import React from 'react';
import { user } from './storages/user';

import { storageConfig } from "@webcored/react-local-storage";

storageConfig({
  namespace: 'app',
  delimiter: '/'
  react: React
  storages: {
    user
  }
}
Enter fullscreen mode Exit fullscreen mode

19