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:
- Read a cookie: Retrieve the value of a specific cookie by its name.
- Write a cookie: Set or update the value of a cookie, with options for expiration, path, domain, and secure flags.
- 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
undefinedif not found). - A function to set/update the cookie's value. This function should accept the new value (string) and an optional
optionsobject. - A function to delete the cookie.
- The current value of the cookie (a string, or
- The
setfunction should accept anoptionsobject with the following optional properties:expires: ADateobject 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: TheSameSiteattribute 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' fromdocument.cookie. - Calling the
setfunction withsetValue('newValue')should update the cookie in the browser and trigger a re-render. - Calling the
setfunction withsetValue('newValue', { expires: new Date(Date.now() + 86400000) })should set the cookie with an expiration date of 24 hours from now. - Calling the
deleteCookiefunction should remove the cookie from the browser and update the hook's state toundefined.
Edge Cases to Consider:
- Cookie not found initially.
- Cookie expiration handling.
- Encoding/decoding cookie values (though
document.cookiehandles 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
expiresoption can be aDateobject 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.cookiestring when setting a cookie, including all the specified options. - Remember to handle the case where a cookie might not exist.
- The
setfunction should likely useuseStateinternally 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.