Enhanced state management hooks that provide convenient patterns for common state scenarios beyond basic useState functionality.
Manages boolean state with convenient action methods for common boolean operations.
/**
* Manages boolean state with convenient toggle and set methods
* @param defaultValue - Initial boolean value (defaults to false)
* @returns Array containing current value and actions object
*/
function useBoolean(defaultValue?: boolean): [boolean, Actions];
interface Actions {
/** Set state to true */
setTrue: () => void;
/** Set state to false */
setFalse: () => void;
/** Set state to specific boolean value */
set: (value: boolean) => void;
/** Toggle state between true and false */
toggle: () => void;
}Usage Example:
import { useBoolean } from 'ahooks';
function Modal() {
const [isVisible, { setTrue: show, setFalse: hide, toggle }] = useBoolean(false);
return (
<div>
<button onClick={show}>Show Modal</button>
<button onClick={hide}>Hide Modal</button>
<button onClick={toggle}>Toggle Modal</button>
{isVisible && <div className="modal">Modal Content</div>}
</div>
);
}Generic toggle state management with customizable values beyond boolean types.
/**
* Generic toggle between two values with customizable left/right states
*/
function useToggle<T = boolean>(): [boolean, Actions<T>];
function useToggle<T>(defaultValue: T): [T, Actions<T>];
function useToggle<T, U>(defaultValue: T, reverseValue: U): [T | U, Actions<T | U>];
interface Actions<T> {
/** Set state to left value */
setLeft: () => void;
/** Set state to right value */
setRight: () => void;
/** Set state to specific value */
set: (value: T) => void;
/** Toggle between left and right values */
toggle: () => void;
}Usage Example:
import { useToggle } from 'ahooks';
function ThemeToggler() {
const [theme, { toggle, setLeft, setRight }] = useToggle('light', 'dark');
return (
<div className={`theme-${theme}`}>
<button onClick={toggle}>Toggle Theme</button>
<button onClick={setLeft}>Light Mode</button>
<button onClick={setRight}>Dark Mode</button>
<p>Current theme: {theme}</p>
</div>
);
}Counter state management with optional min/max constraints and increment/decrement actions.
/**
* Manages numeric counter with optional constraints and convenient actions
* @param initialValue - Starting counter value (defaults to 0)
* @param options - Configuration with min/max constraints
* @returns Array containing current value and actions object
*/
function useCounter(initialValue?: number, options?: Options): [number, Actions];
interface Options {
/** Minimum allowed value */
min?: number;
/** Maximum allowed value */
max?: number;
}
interface Actions {
/** Increment by delta (defaults to 1), respecting max constraint */
inc: (delta?: number) => void;
/** Decrement by delta (defaults to 1), respecting min constraint */
dec: (delta?: number) => void;
/** Set to specific value or use updater function, respecting constraints */
set: (value: number | ((c: number) => number)) => void;
/** Reset to initial value */
reset: () => void;
}Usage Example:
import { useCounter } from 'ahooks';
function QuantitySelector() {
const [quantity, { inc, dec, set, reset }] = useCounter(1, {
min: 1,
max: 99
});
return (
<div>
<button onClick={() => dec()}>-</button>
<input
type="number"
value={quantity}
onChange={(e) => set(parseInt(e.target.value) || 1)}
/>
<button onClick={() => inc()}>+</button>
<button onClick={reset}>Reset</button>
<p>Quantity: {quantity}</p>
</div>
);
}Manages object state similar to class component setState, allowing partial updates.
/**
* Manages object state with setState-like partial update functionality
* @param initialState - Initial state object or factory function
* @returns Array containing current state and updater function
*/
function useSetState<T extends Record<string, any>>(
initialState?: T | (() => T)
): [T, (patch: Partial<T> | ((prev: T) => Partial<T>)) => void];Usage Example:
import { useSetState } from 'ahooks';
interface UserForm {
name: string;
email: string;
age: number;
}
function UserProfile() {
const [user, setUser] = useSetState<UserForm>({
name: '',
email: '',
age: 0
});
return (
<form>
<input
value={user.name}
onChange={(e) => setUser({ name: e.target.value })}
placeholder="Name"
/>
<input
value={user.email}
onChange={(e) => setUser({ email: e.target.value })}
placeholder="Email"
/>
<input
type="number"
value={user.age}
onChange={(e) => setUser({ age: parseInt(e.target.value) })}
placeholder="Age"
/>
<button onClick={() => setUser((prev) => ({ ...prev, age: prev.age + 1 }))}>
Increment Age
</button>
</form>
);
}useState with additional getter function for accessing current state synchronously.
/**
* useState with getter function for accessing current state
* @param initialState - Initial state value or factory function
* @returns Array containing current state, setter, and getter function
*/
function useGetState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>, GetStateAction<S>];
type GetStateAction<S> = () => S;Usage Example:
import { useGetState } from 'ahooks';
function Timer() {
const [count, setCount, getCount] = useGetState(0);
useEffect(() => {
const interval = setInterval(() => {
// Get current state synchronously in callback
const currentCount = getCount();
setCount(currentCount + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
return <div>Count: {count}</div>;
}useState with built-in reset functionality to return to initial state.
/**
* useState with reset functionality to return to initial state
* @param initialState - Initial state value or factory function
* @returns Array containing current state, setter, and reset function
*/
function useResetState<S>(
initialState: S | (() => S)
): [S, Dispatch<SetStateAction<S>>, () => void];useState that prevents state updates after component unmount to avoid memory leaks.
/**
* useState that prevents state updates after component unmount
* @param initialState - Initial state value or factory function
* @returns Array containing current state and safe setter function
*/
function useSafeState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];useState that uses requestAnimationFrame for state updates to optimize rendering performance.
/**
* useState that uses requestAnimationFrame for optimized state updates
* @param initialState - Initial state value
* @returns Array containing current state and RAF-optimized setter
*/
function useRafState<S>(initialState?: S): [S, Dispatch<SetStateAction<S>>];Manages controlled/uncontrolled component state patterns for building flexible form components.
/**
* Manages controlled/uncontrolled component state patterns
* Standard props version for typical controlled components
*/
function useControllableValue<T = any>(props: StandardProps<T>): [T, (v: SetStateAction<T>) => void];
/**
* Extended version with custom prop names and transformation
*/
function useControllableValue<T = any>(
props?: Props,
options?: Options<T>
): [T, (v: SetStateAction<T>, ...args: any[]) => void];
interface StandardProps<T> {
/** Controlled value */
value: T;
/** Default value for uncontrolled mode */
defaultValue?: T;
/** Change handler for controlled mode */
onChange: (val: T) => void;
}
interface Props {
[key: string]: any;
}
interface Options<T> {
/** Default value when uncontrolled */
defaultValue?: T;
/** Custom prop name for defaultValue (default: 'defaultValue') */
defaultValuePropName?: string;
/** Custom prop name for value (default: 'value') */
valuePropName?: string;
/** Custom prop name for onChange (default: 'onChange') */
trigger?: string;
}Usage Example:
import { useControllableValue } from 'ahooks';
interface CustomInputProps {
value?: string;
defaultValue?: string;
onChange?: (value: string) => void;
}
function CustomInput(props: CustomInputProps) {
const [value, setValue] = useControllableValue(props);
return (
<input
value={value}
onChange={(e) => setValue(e.target.value)}
/>
);
}
// Usage as controlled component
<CustomInput value={controlledValue} onChange={setControlledValue} />
// Usage as uncontrolled component
<CustomInput defaultValue="initial" />Reactive state management using Proxy for automatic reactivity when object properties change.
/**
* Creates reactive state using Proxy for automatic reactivity
* @param initialState - Initial state object
* @returns Reactive proxy object that triggers re-renders on changes
*/
function useReactive<S extends Record<string, any>>(initialState: S): S;Usage Example:
import { useReactive } from 'ahooks';
function ReactiveForm() {
const form = useReactive({
username: '',
password: '',
rememberMe: false
});
return (
<div>
<input
value={form.username}
onChange={(e) => form.username = e.target.value}
placeholder="Username"
/>
<input
type="password"
value={form.password}
onChange={(e) => form.password = e.target.value}
placeholder="Password"
/>
<label>
<input
type="checkbox"
checked={form.rememberMe}
onChange={(e) => form.rememberMe = e.target.checked}
/>
Remember Me
</label>
<p>Form: {JSON.stringify(form)}</p>
</div>
);
}// React types
type Dispatch<A> = (value: A) => void;
type SetStateAction<S> = S | ((prevState: S) => S);