React custom hook: useLocalStorage

useLocalStorage

React is a popular front-end JavaScript library for building user interfaces. It provides developers with many built-in hooks such as useState and useEffect that make it easier to manage state and side effects in their applications. However, sometimes you may find that these hooks don’t meet your specific needs. That’s where custom hooks come in.

What is a Custom Hook?

A custom hook is a function that uses one or more of the built-in React hooks to create a new hook. It’s a way to abstract away complex logic and reuse it across multiple components. Custom hooks can be used to manage state, handle side effects, and provide a simpler way to work with APIs and other external services.

Requirements for Creating a Custom Hook

To create a custom hook, you need to follow a few guidelines:

  1. It should start with the word “use
  2. It should be a pure function, meaning it should not have any side effects or modify the component’s state directly.
  3. It should return an array, object, or value that can be used in a component.

What is useLocalStorage?

useLocalStorage is a custom hook that allows you to store and retrieve data from the browser’s localStorage API. The localStorage API allows you to store data on the client-side, so it’s persistent even after the user closes the browser. This makes it a great way to store user preferences or any other data that you want to persist across sessions.

How to Create useLocalStorage Custom Hook

Here’s an example of how to create a useLocalStorage custom hook:

import { useState, useEffect } from "react";

const useLocalStorage = (key: string, initialValue: any = "") => {
  const [value, setValue] = useState(() => {
    try {
      const item = JSON.parse(localStorage.getItem(key) || "");
      if (item) return item;
      if (initialValue instanceof Function) return initialValue();
      return initialValue;
    } catch (err) {
      return initialValue;
    }
  });

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [value, key]);

  return [value, setValue];
};

export default useLocalStorage;


In this example, we define a function called useLocalStorage that takes two arguments: key and initialValue. We then use the useState hook to create a value state variable, which is set to the value retrieved from localStorage, or the initialValue if there is no value stored. We also have to account for the fact that useState doesn’t always use a specific “value”, you can also use a callback function inside the useState (like in the example above). In a situation like this, we have to include the following line to return the callback function:

if (initialValue instanceof Function) return initialValue();

The setValue function updates the value state and saves the new value to localStorage.

Finally, we return an array with the value and setValue function. This array can be used in a component to read and write values to localStorage.

Now let’s use the custom hook in our component

import useLocalStorage from "./hooks/useLocalStorage";

export default function App() {
  const [name, setName] = useLocalStorage("name", "");

  return (
    <div className="App">
      <input
        type="text"
        name="myname"
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
    </div>
  );
}

In our component, we first import the custom hook, then use it just like we would with useState, except in this case we specify a localStorage key of “name” and an initialValue of an empty string “”. The component has an input text box with the usual value and onChange properties. When you type in anything in the input box, the onClick method updates the localStorage with the help of useLocalStorage. When you refresh the page, the string in the text box persists. You can inspect the page and note the localStorage being changed as you type.

Things to be careful of when creating a Custom Hook

When creating a custom hook, there are a few things to keep in mind:

  1. Don’t mix concerns: A custom hook should focus on a single concern, such as managing state or handling side effects. Don’t try to do too much in one hook.
  2. Don’t modify the component’s state directly: A custom hook should not modify the component’s state directly. Instead, it should return a value that can be used to update the component’s state.
  3. Don’t use other hooks conditionally: If you need to use multiple hooks in a custom hook, make sure to use them in the same order every time. React relies on the order of hooks to maintain the state between renders.

Conclusion

Custom hooks are a powerful way to abstract away complex logic and make it reusable across multiple components. The useLocalStorage custom hook is a great example of how you can use custom hooks to interact with external APIs or services in a simpler way.

By following the guidelines for creating custom hooks, you can create your own hooks that simplify your code and make it easier to maintain. Just remember to keep each hook focused on a single concern, avoid modifying the component state directly, and use hooks in a consistent order to avoid errors.

Overall, custom hooks are a powerful tool in the React developer’s toolbox, and can make your code more modular, reusable, and maintainable. With a little practice, you can create your own custom hooks that solve specific problems in your applications and make your code more efficient and effective. We will look at other custom hooks in later articles.

You Might Also Like