or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

async-operations.mddata-structures.mddom-interactions.mdeffects.mdindex.mdperformance.mdspecialized-hooks.mdstate-management.mdstorage.mdtimers.md
tile.json

state-management.mddocs/

State Management

Enhanced state management hooks that provide convenient patterns for common state scenarios beyond basic useState functionality.

Capabilities

Boolean State Management

useBoolean

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>
  );
}

useToggle

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>
  );
}

Numeric State Management

useCounter

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>
  );
}

Object State Management

useSetState

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>
  );
}

Enhanced State Patterns

useGetState

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>;
}

useResetState

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];

useSafeState

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>>];

useRafState

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>>];

Controlled Components

useControllableValue

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

useReactive

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>
  );
}

Common Types

// React types
type Dispatch<A> = (value: A) => void;
type SetStateAction<S> = S | ((prevState: S) => S);