DEV Community

Cover image for Build a useLocalStorage React Hook Package (Contribute to Open Source with Me)
Nick Scialli (he/him)
Nick Scialli (he/him)

Posted on • Edited on

Build a useLocalStorage React Hook Package (Contribute to Open Source with Me)

I have been dogfooding a useLocalStorage React hook for a while and just yesterday open-sourced it on npm as the uselocalstorage package.

Do you have an interest in contributing to open source? If so, I'm looking for help, regardless of your level of experience!

First time contributors welcome!

If youโ€™re interested, be sure to follow the GitHub repo here and check out the open issues.


Please give this post a ๐Ÿ’“, ๐Ÿฆ„, and ๐Ÿ”– to help grow the effort!


About the Hook

The useLocalStorage hook acts a lot like the useState hook, except it also persists your stateful data to your browser's local storage. The hook is available in JavaScript and Typescript.

Yes, There are Alternatives!

I am well aware that there are alternatives, even good alternatives, to this package! That being said, I also believe that more attempts to build something can only be better as competition allows the best solutions to rise to the top.

Help I'm Looking For

I have started outlining the various tasks I'm looking for help with in the Github Issues Page. Here's what I have so far:

  • Add CONTRIBUTING.md
  • Add CODE_OF_CONDUCT.md
  • Prevent sync issues in different tabs by using a "storage" window event listener.
  • Use the hook and suggest more features!

Note that some of these probably require some React/Typescript experience, but others are administrative help that's just as important and anyone can help with!

Installation

Install with npm

npm i use-local-storage
Enter fullscreen mode Exit fullscreen mode

Install with yarn

yarn add use-local-storage
Enter fullscreen mode Exit fullscreen mode

Basic Usage

In its most basic form, the useLocalStorage hook just needs the Local Storage key you wish to use. However, it's advised that you also provide a default value as a second argument in the event that they key does not yet exist in Local Storage.

The following usage will persist the username variable in a "name" key in Local Storage. It will have a default/initial value of an empty string "". This default value will only be used if there is no value already in Local Storage.

import useLocalStorage from "use-local-storage";

function MyComponent() {
  const [username, setUsername] = useLocalStorage("name", "");

  return (
    <>
      <input
        value={username}
        onChange={(e) => {
          setUsername(e.target.value);
        }}
      />
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Note: By default, the useLocalStorage hook uses JSON.stringify and JSON.parse to serialize and parse the data, respectively. A custom serializer and/or parser can be configured if desired (discussed below in the Advanced Usage section).

Typescript Use

The type of username will be inferred from your default value. In this case, the type of string will be inferred.

If you use useLocalStorage without providing a default value, or you simply want to specify that username is actually of a different type, you should pass the type of your data as a generic:

import useLocalStorage from "use-local-storage";

function MyComponent() {
  const [username, setUsername] = useLocalStorage<string>("name");

  return (
    <>
      <input
        value={username}
        onChange={(e) => {
          setUsername(e.target.value);
        }}
      />
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Advanced Usage / Options

the useLocalStorage hook takes an optional third options argument. This allows you to configure a custom serializer and/or parser if you need to use something other than JSON.stringify and JSON.parse. The options object also has a logger key to log an errors caught in the hook.

const options = {
  serializer: (obj) => {
    /* Serialize logic */
    return someString;
  },
  parser: (str) => {
    /* Parse logic */
    return parsedObject;
  },
  logger: (error) => {
    // Do some logging
  },
};

const [data, setData] = useLocalStorage("data", { foo: "bar" }, options);
Enter fullscreen mode Exit fullscreen mode

Attribution

Storage icon made by DinosoftLabs from www.flaticon.com

Top comments (7)

Collapse
 
peerreynders profile image
peerreynders • Edited

PSA:

  1. Be aware of the risks of localStorage (or any other client-side storage solution).
  2. Consider alternatives available that may (or may not) be a better fit for your particular use case - e.g. IndexedDB with idb - Working with IndexedDB, Best Practices for Using IndexedDB.
Collapse
 
prashanthr profile image
Prashanth R.

Great post, love the hook! I'll try and see if I can help out in my spare time. Cheers!

Collapse
 
nas5w profile image
Nick Scialli (he/him)

Thank you Prashanth!

Collapse
 
mstanciu552 profile image
Mihai Stanciu

This sounds like a really cool idea. You could open an issue to the official React repo to introduce this to them.

Collapse
 
nas5w profile image
Nick Scialli (he/him)

Thanks! They havenโ€™t generally been open to new Hooks, preferring the community publish their own packages. For now, Iโ€™m planning on keeping this as an independent open source effort!

Collapse
 
nas5w profile image
Nick Scialli (he/him)

Added a new enhancement request to add a storage event listener to prevent data sync issues!

Collapse
 
myzel394 profile image
Myzel394

Add it to usehooks.com