DEV Community

Ajey N
Ajey N

Posted on • Edited on

Persist your React State in the Browser

The Problem

Have you ever wanted to persist your React state in the browser? Have you ever created a long form and wished its data wouldn't vanish when you refresh the page before you submit it?

well, I have too.

Brainstorming solutions

I've been thinking about this for a while.
Basically, you have to store the form data in the browser. There are a few ways to do this. There is localStorage, sessionStorage, and cookies. These work great for small amounts of data and simple forms. I wanted to build something that is robust, can handle variety of data, and as simple as using useState hook in React.

That's when I came across IndexedDB.

Did you know the browser has its own database? I mean not key:value pairs like localStorage, but an actual database that you can store and query data from!!

Mind Blown

IndexedDB

This is what the official MDN doc says about IndexedDB:

IndexedDB is a low-level API for client-side storage of significant amounts of structured data, including files/blobs. This API uses indexes to enable high-performance searches of this data. While Web Storage is useful for storing smaller amounts of data, it is less useful for storing larger amounts of structured data. IndexedDB provides a solution.

In simple terms, you can store large amounts of complex data and also query it quickly and efficiently just like you would with a database. Web storage would store small amounts (~10MB) of data in the form of strings upon which you cannot query.

And guess what? You can even store files and blobs in IndexedDB!

wow gif

The Solution

If you look at the IndexedDB API documentation, you will see that it is fairly complex to setup and use. I wanted something that is as simple as using useState hook. Infact I want it to have same syntax and same ease of use as useState hook.

So I started building a simple library that will help you store and query your data in IndexedDB just as easily as you would with useState.

That's how use-db-state was born.

Introducing use-db-state

use-db-state is a custom React hook that allows you to persist state in the browser using IndexedDB. It handles all the complexity of IndexedDB, giving you a simple and familiar interface to work with.

Let's see how you can use it.

Installation

First, you need to install the library via npm:

npm install use-db-state
Enter fullscreen mode Exit fullscreen mode

Usage

Here's a simple example to get you started:

please go through the documentation for detailed explaination of the parameters

import React from 'react';
import { useDbState } from 'use-db-state';

const SimpleForm = () => {
  const [value, setValue] = useDbState('formInput', '');

  return (
    <div>
      <h1>Persisted Form</h1>
      <input 
        type="text" 
        value={value} 
        onChange={(e) => setValue(e.target.value)} 
        placeholder="Type something..." 
      />
      <p>Persisted Value: {value}</p>
    </div>
  );
};

export default SimpleForm;
Enter fullscreen mode Exit fullscreen mode

And just like that your state will persist even if you refresh the page!
Your state is now stored in IndexedDB. If you want to see where your data is stored, open your browser's developer console, go to Applications tab, and on the left panel look for IndexedDB! Click on it and you should see your data inside.

Going Deeper

But wait, there's more! use-db-state also comes with a handy hook called useDbKeyRemover. This hook allows you to remove specific keys from IndexedDB.

Why is useDbKeyRemover Important?

When dealing with persisted state, there are situations where you may need to clean up or remove specific entries from your IndexedDB store. For instance:

  • Form Resets: After submitting a form, you might want to clear the saved input values to avoid stale data when the user revisits the form.
  • User Logout: On user logout, you might want to clear user-specific data from IndexedDB to ensure privacy and data security.
  • Data Updates: Sometimes, you need to remove outdated data to make way for new, updated data. By using useDbKeyRemover, you can easily remove specific keys without having to deal with the low-level complexities of IndexedDB.

Here's a more complex example demonstrating both useDbState and useDbKeyRemover:
please go through the documentation for detailed explaination of the parameters

Example: Form with Key Removal

import React from 'react';
import { useDbState, useDbKeyRemover } from 'use-db-state';

const FormWithKeyRemoval = () => {
  const [name, setName] = useDbState('name', '');
  const [email, setEmail] = useDbState('email', '');
  const removeKey = useDbKeyRemover();

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Form submitted:', { name, email });
    setName('');
    setEmail('');
    removeKey('name');
    removeKey('email');
  };

  return (
    <div>
      <h1>Form with Key Removal</h1>
      <form onSubmit={handleSubmit}>
        <div>
          <label>
            Name:
            <input 
              type="text" 
              value={name} 
              onChange={(e) => setName(e.target.value)} 
            />
          </label>
        </div>
        <div>
          <label>
            Email:
            <input 
              type="email" 
              value={email} 
              onChange={(e) => setEmail(e.target.value)} 
            />
          </label>
        </div>
        <button type="submit">Submit</button>
      </form>
    </div>
  );
};

export default FormWithKeyRemoval;
Enter fullscreen mode Exit fullscreen mode

When to Use use-db-state

use-db-state is perfect for scenarios where you need to persist state across page reloads or browser sessions. Some common use cases include:

  • Forms: Prevent users from losing their input data in case they accidentally refresh the page.
  • User Preferences: Persist theme, language, or other user settings.
  • Shopping Carts: Maintain cart contents between sessions.
  • Complex Forms: Save progress in multi-step forms.
  • And much more!!

Conclusion

Persisting state in the browser doesn't have to be complex. With use-db-state, you can leverage the power of IndexedDB with the simplicity of useState. This library abstracts away the complexities, allowing you to focus on building great user experiences.

Give use-db-state a try in your next project and make state persistence a breeze!

hifi

Happy coding!


Feel free to reach out if you have any questions or need further assistance. You can find the full documentation on my GitHub repository.

If you found this article helpful, share it with your fellow developers and spread the word about use-db-state!

You can follow me on github and Linkedin

Top comments (0)