How to use local storage with React Hooks

H
andrewgbliss
9 months ago

This article will cover how to use local storage with React hooks

. . .

Github repo

https://github.com/EntryLevelDeveloperTraining/todos

What is local storage?

Local storage is a way that we can save the data from our application into the browser. The data will persist when we refresh the page. Local storage is very useful to store data that you want to save and persist.

Let's go to a website called usehooks.com. There are several hooks we can use, let's grab the useLocalStorage hook.

https://usehooks.com/

Let's setup a React hook called useLocalStorage:

import { useState } from "react";

function useLocalStorage(key, initialValue) {
  // State to store our value
  // Pass initial state function to useState so logic is only executed once
  const [storedValue, setStoredValue] = useState(() => {
    try {
      // Get from local storage by key
      const item = window.localStorage.getItem(key);
      // Parse stored json or if none return initialValue
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      // If error also return initialValue
      console.log(error);
      return initialValue;
    }
  });

  // Return a wrapped version of useState's setter function that ...
  // ... persists the new value to localStorage.
  const setValue = (value) => {
    try {
      // Allow value to be a function so we have same API as useState
      const valueToStore =
        value instanceof Function ? value(storedValue) : value;
      // Save state
      setStoredValue(valueToStore);
      // Save to local storage
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
    } catch (error) {
      // A more advanced implementation would handle the error case
      console.log(error);
    }
  };

  return [storedValue, setValue];
}

export default useLocalStorage;

Now we can update our Theme component to remember if they switch on Dark Mode. Then when they refresh it will be in Dark Mode already.

import React from "react";
import { createMuiTheme } from "@material-ui/core/styles";
import { ThemeProvider } from "@material-ui/styles";
import { CssBaseline } from "@material-ui/core";
import purple from "@material-ui/core/colors/purple";
import green from "@material-ui/core/colors/green";
import useLocalStorage from "../../hooks/useLocalStorage";

const theme = createMuiTheme({
  palette: {
    type: "light",
    primary: purple,
    secondary: green,
  },
});

const themeDark = createMuiTheme({
  palette: {
    type: "dark",
    primary: purple,
    secondary: green,
  },
});

const Theme = (props) => {
  const { children, darkMode } = props;
  const defaultTheme = darkMode ? themeDark : theme;
  return (
    <ThemeProvider theme={defaultTheme}>
      <CssBaseline />
      {children}
    </ThemeProvider>
  );
};

export const withTheme = (Component) => {
  return (props) => {
    const [darkMode, setDarkMode] = useLocalStorage("darkMode", false);
    return (
      <Theme darkMode={darkMode}>
        <Component {...props} darkMode={darkMode} setDarkMode={setDarkMode} />
      </Theme>
    );
  };
};

We can also update the Todo context to store the todos in local storage:

import useLocalStorage from "../../../hooks/useLocalStorage";

const [todos, setTodos] = useLocalStorage("todos", [
    {
      id: 0,
      text: "feed the dog",
      completed: false,
    },
    {
      id: 1,
      text: "go shopping",
      completed: false,
    },
    {
      id: 2,
      text: "hang glide",
      completed: false,
    },
  ]);

You can use the useLocalStorage in place of the useState hook. All you need to do is give it a name, and then pass in the state you want to persist.


H
andrewgbliss
9 months ago