DEV Community

Cover image for Managing Browser Cookies in React with useCookie Hook
Saiful Islam
Saiful Islam

Posted on

Managing Browser Cookies in React with useCookie Hook

Browser cookies are a lightweight way to store data that needs to persist between sessions or across different parts of your application. In this post, we’ll explore how to build a custom React hook, useCookie, to make working with cookies seamless in your React applications.


1. Cookie Utility Functions

Before we build the useCookie hook, let’s create a set of helper functions to handle common operations with browser cookies: setting, getting, and removing cookies.


setCookie: Add or Update a Cookie

The setCookie function allows us to save a key-value pair in cookies with an optional expiration time.

export function setCookie(key: string, value: unknown, expireDays = 1): void {
  const d = new Date();

  d.setTime(d.getTime() + expireDays * 24 * 60 * 60 * 1000);

  document.cookie = `${key}=${value}; expires=${d.toUTCString()}; path=/`;
}
Enter fullscreen mode Exit fullscreen mode
  • What It Does:
    • Takes a key, value, and expireDays (default is 1 day).
    • Computes the expiration date.
    • Creates a cookie string with the provided key-value pair and expiration.
  • Usage:
setCookie("theme", "dark", 7); // Saves a cookie for 7 days
Enter fullscreen mode Exit fullscreen mode

getCookie: Retrieve a Cookie Value

The getCookie function retrieves the value of a cookie by its key.

export function getCookie(key: string): string | undefined {
  const name = `${key}=`;

  const decodedCookie = decodeURIComponent(document.cookie);

  const ca = decodedCookie.split(";");

  for (let i = 0; i < ca.length; i++) {
    let c = ca[i];
    while (c.charAt(0) === " ") {
      c = c.substring(1);
    }
    if (c.indexOf(name) === 0) {
      return c.substring(name.length, c.length);
    }
  }

  return undefined;
}
Enter fullscreen mode Exit fullscreen mode
  • How It Works:
    • Decodes the document.cookie string for readability.
    • Splits cookies into an array and searches for the specified key.
    • Returns the value or undefined if the key isn’t found.
  • Usage:
const theme = getCookie("theme"); // Retrieves "dark"
Enter fullscreen mode Exit fullscreen mode

removeCookie: Delete a Cookie

The removeCookie function removes a cookie by overwriting it with an empty value and no expiration date.

export function removeCookie(key: string) {
  document.cookie = `${key}=; path=/`;
}
Enter fullscreen mode Exit fullscreen mode
  • Usage:
removeCookie("theme"); // Deletes the "theme" cookie
Enter fullscreen mode Exit fullscreen mode

2. The useCookie Hook

The useCookie hook combines the cookie utility functions with React’s useState to provide an elegant way to manage cookies in your components.


Hook Initialization

import { useState } from "react";
import { getCookie, setCookie, removeCookie } from "@/utils/cookie";

export default function useCookie<T>(key: string, initialValue: T) {
  const [value, setValue] = useState(() => {
    const data = getCookie(key);
    return (data || initialValue) as T;
  });

  // ...additional logic
}
Enter fullscreen mode Exit fullscreen mode
  • Parameters:
    • key: The cookie key to manage.
    • initialValue: The value to use if the cookie doesn’t already exist.
  • State Initialization:
    • Fetches the cookie’s current value using getCookie.
    • Defaults to initialValue if the cookie doesn’t exist.

Dispatching State Changes

The handleDispatch function updates both the local state and the cookie.

function handleDispatch(action: DispatchAction<T>) {
  if (typeof action === "function") {
    setValue((prevState) => {
      const newValue = (action as (prevState: T) => T)(prevState);
      setCookie(key, newValue);
      return newValue;
    });
  } else {
    setValue(action);
    setCookie(key, action);
  }
}
Enter fullscreen mode Exit fullscreen mode
  • How It Works:
    • If action is a function, it applies it to the current state and computes the new value.
    • Otherwise, it directly sets the state and updates the cookie.
  • Cookie Sync:
    • Calls setCookie to ensure the browser cookie stays in sync with the state.

Clearing the State

The clearState function removes the cookie and resets the state.

function clearState() {
  removeCookie(key);
  setValue(undefined as T);
}
Enter fullscreen mode Exit fullscreen mode
  • What It Does:
    • Deletes the cookie using removeCookie.
    • Resets the local state to undefined.

Returning the Hook’s API

The hook exposes an array containing the current value, a dispatcher function, and a clear function.

return [value, handleDispatch, clearState] as const;
Enter fullscreen mode Exit fullscreen mode
  • API:
    1. value: The current value of the cookie.
    2. handleDispatch: A function to update the state and cookie.
    3. clearState: A function to clear the state and remove the cookie.

3. Using the useCookie Hook

Here’s an example of how to use the useCookie hook in a React component:

import useCookie from "@/hooks/useCookie";

function ThemeSwitcher() {
  const [theme, setTheme, clearTheme] = useCookie<string>("theme", "light");

  return (
    <div>
      <h1>Current Theme: {theme}</h1>
      <button onClick={() => setTheme("light")}>Light Mode</button>
      <button onClick={() => setTheme("dark")}>Dark Mode</button>
      <button onClick={clearTheme}>Clear Theme</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
  • Key Features
    • The theme value is stored in a cookie and persists across sessions.
    • Changing the theme updates both the state and the cookie.
    • The clearTheme function resets the theme and removes the cookie.

4. Advantages of useCookie Hook

  • Simplified Cookie Management: Abstracts cookie logic into a reusable hook.
  • State Synchronization: Keeps React state in sync with browser cookies.
  • Error Handling: Built-in mechanisms for decoding and handling cookies.

Conclusion

The useCookie hook makes it easier to manage browser cookies in your React applications while maintaining type safety and a clean codebase. With this hook, you can handle cookie-based state management effortlessly and avoid repetitive boilerplate code.

Ready to integrate this hook into your projects? Let me know how it works for you or share your improvements!

Top comments (0)