Universal cookies for React that work seamlessly across client-side and server-side rendering environments
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Higher-order component pattern for injecting cookie functionality into class components or components that need cookie access via props rather than hooks.
Higher-order component that wraps a component and injects cookie-related props, providing an alternative to the useCookies hook for class components or when prop-based access is preferred.
/**
* Higher-order component that injects cookie functionality via props
* @param WrappedComponent - Component to enhance with cookie props
* @returns Enhanced component with cookie props injected
*/
function withCookies<T extends ReactCookieProps>(
WrappedComponent: React.ComponentType<T>,
): React.ComponentType<Omit<T, keyof ReactCookieProps>>;Injected Props:
cookies: Cookies instance with get/set/remove methodsallCookies: Object containing all current cookies as key-value pairsStatic Properties:
WrappedComponent: Reference to the original componentdisplayName: Component display name for debuggingUsage Examples:
import React, { Component } from 'react';
import { withCookies, Cookies, ReactCookieProps } from 'react-cookie';
// Class component example
interface Props extends ReactCookieProps {
cookies: Cookies;
allCookies: { [name: string]: any };
title: string;
}
interface State {
username: string;
}
class UserProfile extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
username: props.cookies.get('username') || ''
};
}
handleLogin = (username: string) => {
const { cookies } = this.props;
cookies.set('username', username, { path: '/' });
this.setState({ username });
};
handleLogout = () => {
const { cookies } = this.props;
cookies.remove('username', { path: '/' });
this.setState({ username: '' });
};
render() {
const { title, allCookies } = this.props;
const { username } = this.state;
return (
<div>
<h1>{title}</h1>
{username ? (
<div>
<p>Welcome, {username}!</p>
<button onClick={this.handleLogout}>Logout</button>
</div>
) : (
<button onClick={() => this.handleLogin('john_doe')}>Login</button>
)}
<details>
<summary>All Cookies</summary>
<pre>{JSON.stringify(allCookies, null, 2)}</pre>
</details>
</div>
);
}
}
// Enhance component with cookie functionality
const EnhancedUserProfile = withCookies(UserProfile);
// Usage - note that cookie props are automatically injected
function App() {
return (
<CookiesProvider>
<EnhancedUserProfile title="My App" />
</CookiesProvider>
);
}
// Functional component example
interface FunctionalProps extends ReactCookieProps {
cookies: Cookies;
allCookies: { [name: string]: any };
label: string;
}
function CookieDisplay({ cookies, allCookies, label }: FunctionalProps) {
const handleSetCookie = () => {
cookies.set('demo', new Date().toISOString());
};
return (
<div>
<h2>{label}</h2>
<button onClick={handleSetCookie}>Set Demo Cookie</button>
<p>Demo cookie: {cookies.get('demo')}</p>
<p>All cookies: {Object.keys(allCookies).length}</p>
</div>
);
}
const EnhancedCookieDisplay = withCookies(CookieDisplay);The cookies prop injected by withCookies provides direct access to all cookie management methods.
interface Cookies {
/** Get a single cookie value */
get(name: string, options?: CookieGetOptions): any;
/** Get all cookies as an object */
getAll(options?: CookieGetOptions): { [name: string]: any };
/** Set a cookie value */
set(name: string, value: any, options?: CookieSetOptions): void;
/** Remove a cookie */
remove(name: string, options?: CookieSetOptions): void;
/** Add listener for cookie changes */
addChangeListener(callback: () => void): void;
/** Remove cookie change listener */
removeChangeListener(callback: () => void): void;
/** Manually update cookies from browser */
update(): void;
}Direct cookie manipulation:
class AdvancedCookieComponent extends Component<Props> {
componentDidMount() {
const { cookies } = this.props;
// Get single cookie
const theme = cookies.get('theme');
// Get all cookies
const allCookies = cookies.getAll();
// Set cookie with options
cookies.set('lastVisit', new Date().toISOString(), {
expires: new Date(Date.now() + 86400000), // 24 hours
secure: true,
sameSite: 'strict'
});
// Remove cookie (must match original path/domain)
cookies.remove('temporary', { path: '/' });
// Listen for cookie changes
cookies.addChangeListener(this.handleCookieChange);
}
componentWillUnmount() {
this.props.cookies.removeChangeListener(this.handleCookieChange);
}
handleCookieChange = () => {
// Force component update when cookies change
this.forceUpdate();
};
render() {
return <div>Component content</div>;
}
}The HOC automatically handles cookie change detection and component updates.
class LifecycleExample extends Component<Props> {
componentDidMount() {
// HOC automatically listens for cookie changes
console.log('Component mounted with cookies:', this.props.allCookies);
}
componentDidUpdate(prevProps: Props) {
// Compare cookie changes
if (prevProps.allCookies !== this.props.allCookies) {
console.log('Cookies changed:', this.props.allCookies);
}
}
render() {
// Component automatically re-renders when cookies change
return <div>Cookie count: {Object.keys(this.props.allCookies).length}</div>;
}
}
const EnhancedLifecycleExample = withCookies(LifecycleExample);Access the original component and display name through static properties.
const OriginalComponent = ({ title }: { title: string }) => <h1>{title}</h1>;
const EnhancedComponent = withCookies(OriginalComponent);
// Access original component
console.log(EnhancedComponent.WrappedComponent === OriginalComponent); // true
// Display name for debugging
console.log(EnhancedComponent.displayName); // "withCookies(OriginalComponent)"
// Use in React DevTools or testing
expect(EnhancedComponent.WrappedComponent).toBe(OriginalComponent);Proper TypeScript usage with the HOC pattern.
// Define props interface that extends ReactCookieProps
interface MyComponentProps extends ReactCookieProps {
cookies: Cookies;
allCookies: { [name: string]: any };
// Your custom props
title: string;
onSave?: (data: any) => void;
}
class MyComponent extends Component<MyComponentProps> {
render() {
const { cookies, allCookies, title, onSave } = this.props;
// TypeScript knows about all props including injected ones
return <div>{title}</div>;
}
}
// HOC removes cookie-related props from required props
const Enhanced = withCookies(MyComponent);
// Usage - only custom props are required
<Enhanced title="Hello" onSave={handleSave} />Install with Tessl CLI
npx tessl i tessl/npm-react-cookie