An useful custom hook for your beginner React projects.

An useful custom hook for your beginner React projects.

ยท

3 min read

To all aspiring front-end developers out there, learning React for the first time can present some challenges. For instance, imagine you're learning React by creating a Todo application and writing a bit of code every day. To test the app's behaviour, you need a substantial number of todos in your list, so you create them. However, at the end of the day, when you wrap up and shut down your laptop or close the browser, all that data is lost ๐Ÿ˜ช.

Now, when you begin working on the app the following day, you must recreate all those todos once more!

One possible solution to this problem is to create a persistent database, such as MongoDB or SQL. However, since you are still learning, you may not want to overcomplicate things just yet.

The useStoredState hook comes to the rescue ๐ŸŽ‰.

Just like the useState hook, our custom useStorageHook creates a state and returns a setState-like function to change the state. Additionally, it stores the state in either localStorage or sessionStorage. When you open the application the next day, it automatically initializes the state with what is stored in the storage. And when you update the state, it gets updated in storage as well.

Pretty neat right?

Here's how you create the useStoredState custom hook.

import { useState, useEffect } from "react";

function useStoredState(storage, defaultValue, stateKey) {
  const storedStateString = storage.getItem(stateKey);
  let storedState;

  try {
    storedState = storedStateString
      ? JSON.parse(storedStateString)
      : defaultValue;
  } catch (err) {
    storedState = defaultValue;
  }

  const [state, setState] = useState(storedState);

  useEffect(() => {
    storage.setItem(stateKey, JSON.stringify(state));
  }, [state, stateKey, storage]);

  const setStoredState = (value) => {
    setState(value);
  };

  return [state, setStoredState];
}

The first argument this function takes is storage, which can be either localStorage or sessionStorage. The second argument is defaultValue, which represents the initial value of the state. The third argument is stateKey, which determines how your state will be stored.

Here's how you use this in a react component:

import "./styles.css";
import Todo from './Todo';
import AddTodoInput from "./AddTodoInput";

export default function Todos() {
  const [todos, setTodos] = useStoredState(localStorage, [], "todos");

  const onAddToDo = (todoName) => {
    setTodos([...todos, {
      name: todoName,
    }]);
  }

  const onCheckTodo = todoName => {
    setTodos(todos.filter(todo => todo.name !== todoName))
  }

  return (
    <div className="App">
      <Todo onCheckTodo={onCheckTodo} />
      <AddTodoInput onAddToDo={onAddToDo} />
    </div>
  );
}

That's it! Your react app now persists data without the need of a server or db connection. Happy coding ๐Ÿค“

PS: You can extend this to implement an app-wide stored state as well.


Follow me on twitter to stay in touch. You can find my writings at devshekhawat.com. Also, subscribe to the newsletter here to get daily updates on ๐Ÿ’ป web development, โ˜€๏ธ life and ๐Ÿ“š productivity.

Did you find this article valuable?

Support Dev Shekhawat by becoming a sponsor. Any amount is appreciated!

ย