React useLocalStorage hook

React uselocalstorage.

In react app state is KING. Managing state efficiently is the key point in your application performance.

State has one issue its temparory. While your app is running its available as soon as you close your tab or browser its gone. You have to re-populate often as per your need.

Sometimes we want to retain some information even though application is closed. In such scenario you can use react's hook feature and create your own custom hook.

useLocalStorage

This hook will act as useState native react hook but also store value to localstoreage. Now when our application closed value is persisted in localstorage. Next time when we reopen our app it useLocalStorage hook will fetch localstorege value and re-populate in our state.

Its feature is so good that you can't even realise that you are storing values and fetching it back. It feels like our state is available all the time without any effort.

useLocalStorage code:

import {useState} from 'react';

// useLocalstorage hook
function useLocalStorage(key, initialValue) {

  // Native React useState function which will store value through life span of App
  // we can use state function to initialise stateand it will executed only once
  const [storedValue, setStoredValue] = useState(() => {
    if (typeof window === "undefined") {
      return initialValue;
    }

    try {
      // try to get value for given key from localstorage
      const item = window.localStorage.getItem(key);

      // parse it as at localstorage we will store all value as JSON.stringify
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      // if we face any issue parsing or fetching value we return initialValue
      console.log(error);
      return initialValue;
    }
  });

  // Our custom function which will act as setter method for our state
  const setValue = (value) => {
    try {
      // to match same API with react's useState we can allow to use Function
      const valueToStore =
        value instanceof Function ? value(storedValue) : value;

      // saving state with given value to actual state
      setStoredValue(valueToStore);

      // we also save it to local storage for next time usage
      if (typeof window !== "undefined") {
        // do not forget to JSON.stringify as localstorage works on strings
        window.localStorage.setItem(key, JSON.stringify(valueToStore));
      }
    } catch (error) {
      // if we face issue we just show error in console 
      // and will do nothing
      console.log(error);
    }
  };

  // now return state value and our setter function
  return [storedValue, setValue];
}

How this hook works

useLocalStorage has to do two things in order to provide persistence feature.

  1. useLocalStorage has to retrive value from localstorage and serve it to actual state in initial start. If there is no value in localstorage then return actual provided initialValue.
  2. When we setState then useLocalStorage has to store that value in to localstorage alsong-side given key for the localstorge.

useLocalStorage works on this two principle to achieve results.

How to use useLocalStorage hook

use of useLocalstorage:

import React from "react";
import useLocalStorage from "./useLocalStorage";

// usage of useLocalstorage
function App() {

  // just use useLocalStorage hook same as useState
  // with first argument as KEY for localstorage
  const [name, setName] = useLocalStorage("name", "CodeRecharge");

  return (
    <div>
      <input
        type="text"
        placeholder="Enter your website"
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
    </div>
  );
}

Above example will persist value of your website even if you refresh page or close the browser tab.

Typescript version of useLocalstorage

Typescript useLocalstorage:

import { useState } from "react";

function useLocalStorage<T>(key: string, initialValue: T) {
  const [storedValue, setStoredValue] = useState<T>(() => {
    if (typeof window === "undefined") {
      return initialValue;
    }
    try {

      const item = window.localStorage.getItem(key);

      return item ? JSON.parse(item) : initialValue;
    } catch (error) {

      console.log(error);
      return initialValue;
    }
  });
  const setValue = (value: T | ((val: T) => T)) => {
    try {

      const valueToStore =
        value instanceof Function ? value(storedValue) : value;

      setStoredValue(valueToStore);

      if (typeof window !== "undefined") {
        window.localStorage.setItem(key, JSON.stringify(valueToStore));
      }
    } catch (error) {

      console.log(error);
    }
  };
  return [storedValue, setValue] as const;
}

Above code snippet is using typescript for type safety. You can use typescrtip version if your project is using typescript.

Related Articles

js interview questions