Hone logo
Hone
Problems

React useCookie Hook Challenge

This challenge asks you to create a custom React hook, useCookie, that simplifies the process of managing cookies within your React applications. This hook will allow you to easily read, write, and delete cookies in a type-safe and idiomatic React way, leveraging React's state management capabilities.

Problem Description

You need to implement a React hook named useCookie that acts as a bridge between your React components and the browser's document.cookie API. The hook should provide functionalities to:

  1. Read a cookie: Retrieve the value of a specific cookie by its name.
  2. Write a cookie: Set or update the value of a cookie, with options for expiration, path, domain, and secure flags.
  3. Delete a cookie: Remove a cookie by its name.

The hook should maintain the cookie's value in React state, so that changes to the cookie are reflected in your component's re-renders.

Key Requirements:

  • The hook should accept the cookie name as a required argument.
  • It should return an array containing:
    • The current value of the cookie (a string, or undefined if not found).
    • A function to set/update the cookie's value. This function should accept the new value (string) and an optional options object.
    • A function to delete the cookie.
  • The set function should accept an options object with the following optional properties:
    • expires: A Date object or a number of days until expiration.
    • path: The path for which the cookie is valid.
    • domain: The domain for which the cookie is valid.
    • secure: A boolean indicating if the cookie should only be sent over HTTPS.
    • sameSite: The SameSite attribute for the cookie ('Strict', 'Lax', 'None').
  • The hook should be implemented in TypeScript and provide type safety for cookie values and options.
  • When the cookie's value changes (either read from the browser or set via the hook), the component using the hook should re-render.
  • The hook should handle the initial read of the cookie when it's first mounted.

Expected Behavior:

  • When useCookie('myCookie') is called, it should initialize with the current value of 'myCookie' from document.cookie.
  • Calling the set function with setValue('newValue') should update the cookie in the browser and trigger a re-render.
  • Calling the set function with setValue('newValue', { expires: new Date(Date.now() + 86400000) }) should set the cookie with an expiration date of 24 hours from now.
  • Calling the deleteCookie function should remove the cookie from the browser and update the hook's state to undefined.

Edge Cases to Consider:

  • Cookie not found initially.
  • Cookie expiration handling.
  • Encoding/decoding cookie values (though document.cookie handles most of this natively, be mindful of special characters if manual manipulation were involved).
  • Browser environments (ensure it works correctly in SSR if applicable, though this challenge focuses on client-side).

Examples

Example 1: Basic Usage

// In your component:
const [username, setUsername, deleteUsername] = useCookie('username');

// Initial render (if 'username' cookie exists):
// username might be 'john.doe'
// setUsername('jane.doe'); // Sets 'username' cookie to 'jane.doe' and re-renders
// deleteUsername(); // Deletes the 'username' cookie and re-renders

Example 2: Setting Cookie with Options

// In your component:
const [sessionToken, setSessionToken] = useCookie('session');

// Set with expiration in 1 hour and secure flag
const expires = new Date(Date.now() + 60 * 60 * 1000);
setSessionToken('my-auth-token', { expires, secure: true });

Example 3: Deleting a Cookie

// In your component:
const [promoShown, setPromoShown, deletePromoShown] = useCookie('promoDismissed');

// Later, when user dismisses promo:
deletePromoShown(); // Removes the 'promoDismissed' cookie

Constraints

  • The hook must be a functional component hook.
  • The implementation must use TypeScript.
  • The hook should not rely on external libraries for cookie management.
  • Performance is important; avoid unnecessary re-reads or DOM manipulations.
  • The expires option can be a Date object or a number representing days.

Notes

  • Consider how you will read and parse existing cookies from document.cookie.
  • Think about how to construct the document.cookie string when setting a cookie, including all the specified options.
  • Remember to handle the case where a cookie might not exist.
  • The set function should likely use useState internally to manage the cookie's value and trigger re-renders.
  • Deleting a cookie involves setting its expiration date to a past date.
  • Be mindful of potential serialization/deserialization if you were to store complex objects, though this challenge focuses on string values.
Loading editor...
typescript