React Hooks Reference

Complete reference for all built-in React hooks — useState, useEffect, useContext, and more.

React hooks let you use state and other React features in function components. They must be called at the top level of a component — never inside loops, conditions, or nested functions.

useState

Adds local state to a function component.

const [state, setState] = useState(initialValue);

// With a lazy initializer (computed once)
const [data, setData] = useState(() => expensiveComputation());

// Updating based on previous state
setCount(prev => prev + 1);
Concept Description
Initial value Used on first render; can be any type or a function returning the initial value
Setter function setState triggers a re-render; pass a value or a function receiving the previous state
Shallow merge Unlike class setState, the setter replaces the value — it does not merge objects
Batching React 18 batches all state updates automatically, even in timeouts and promises

useEffect

Runs side effects after render. The dependency array controls when it re-runs.

// Run after every render
useEffect(() => {
  console.log("rendered");
});

// Run once on mount
useEffect(() => {
  console.log("mounted");
}, []);

// Run when dependencies change
useEffect(() => {
  document.title = `Count: ${count}`;
}, [count]);

// Cleanup on unmount
useEffect(() => {
  const subscription = subscribe();
  return () => subscription.unsubscribe();
}, []);
Concept Description
No deps Runs after every render
Empty deps [] Runs once on mount; cleanup runs on unmount
Dep list [a, b] Runs when any dependency changes
Cleanup return Optional function returned runs before the next effect and on unmount

useContext

Reads context value from the nearest provider. Avoids prop drilling.

const ThemeContext = createContext<"light" | "dark">("light");

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar() {
  const theme = useContext(ThemeContext);
  return <div>Current theme: {theme}</div>;
}
Concept Description
Provider Context.Provider wraps children and supplies the value
Consumer useContext(Context) reads the nearest provider’s value
Default value Used when no provider is found above in the tree
Re-render All consumers re-render when the provider value changes

useReducer

An alternative to useState for complex state logic.

interface State {
  count: number;
}

type Action = { type: "increment" } | { type: "decrement" } | { type: "reset" };

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case "increment": return { count: state.count + 1 };
    case "decrement": return { count: state.count - 1 };
    case "reset":     return { count: 0 };
  }
}

const [state, dispatch] = useReducer(reducer, { count: 0 });

dispatch({ type: "increment" });

useRef

Creates a mutable reference that persists across renders without causing re-renders.

// DOM reference
const inputRef = useRef<HTMLInputElement>(null);
<input ref={inputRef} />;
inputRef.current?.focus();

// Mutable value (not for rendering)
const timerRef = useRef<number>();
timerRef.current = window.setInterval(() => {}, 1000);

useMemo

Memoizes an expensive computation. Only recalculates when dependencies change.

const sortedItems = useMemo(() => {
  return items.toSorted((a, b) => a.name.localeCompare(b.name));
}, [items]);

useCallback

Returns a memoized function reference. Useful when passing callbacks to optimized child components.

const handleClick = useCallback((id: string) => {
  selectItem(id);
}, [selectItem]);

useLayoutEffect

Fires synchronously after all DOM mutations. Use for measuring layout or synchronously updating the DOM.

useLayoutEffect(() => {
  const height = ref.current?.offsetHeight ?? 0;
  setTooltipPosition(height + 8);
}, [ref]);

useId

Generates unique IDs for accessibility attributes. Guaranteed to be stable across server and client.

const id = useId();
<label htmlFor={id}>Name</label>
<input id={id} />;

Custom Hooks

Extract reusable logic into a custom hook. Name must start with use.

function useDebounce<T>(value: T, delay: number): T {
  const [debounced, setDebounced] = useState(value);

  useEffect(() => {
    const timer = setTimeout(() => setDebounced(value), delay);
    return () => clearTimeout(timer);
  }, [value, delay]);

  return debounced;
}

// Usage
const searchTerm = useDebounce(inputValue, 300);