Skip to main content
Hooks are functions that let you “hook into” React state and lifecycle features from function components. They let you use state and other React features without writing a class.

Built-in Hooks

React provides several built-in Hooks for different purposes:

State Hooks

State lets a component remember information like user input.
  • useState - Declares a state variable
  • useReducer - Declares a state variable with reducer logic

Context Hooks

Context lets a component receive information from distant parents without passing it as props.

Ref Hooks

Refs let a component hold information that isn’t used for rendering, like a DOM node.

Effect Hooks

Effects let a component connect to and synchronize with external systems.

Performance Hooks

These hooks help optimize re-rendering performance.

Resource Hooks

These hooks let components access resources without them being part of their state.
  • use - Reads the value of a Promise or Context

Other Hooks

Rules of Hooks

Hooks are JavaScript functions with two important rules:

Only call Hooks at the top level

Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function, before any early returns.
function Component() {
  // ✅ Good: Top level of component
  const [state, setState] = useState(0);
  
  if (condition) {
    // ❌ Bad: Inside condition
    const [other, setOther] = useState(1);
  }
  
  // ✅ Good: Top level
  useEffect(() => {
    // Effect logic
  });
}

Only call Hooks from React functions

Don’t call Hooks from regular JavaScript functions. Instead, you can:
  • ✅ Call Hooks from React function components
  • ✅ Call Hooks from custom Hooks
// ❌ Bad: Regular function
function regularFunction() {
  const [state, setState] = useState(0);
}

// ✅ Good: React component
function Component() {
  const [state, setState] = useState(0);
}

// ✅ Good: Custom Hook
function useCustomHook() {
  const [state, setState] = useState(0);
  return state;
}

Custom Hooks

You can create your own Hooks to extract component logic into reusable functions. Custom Hooks are JavaScript functions whose name starts with “use” and that may call other Hooks.
import { useState, useEffect } from 'react';

function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);
  
  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);
  
  return width;
}

// Usage in component
function MyComponent() {
  const width = useWindowWidth();
  return <div>Window width: {width}px</div>;
}
Custom Hooks let you share stateful logic, not state itself. Each call to a Hook is completely independent from every other call to the same Hook.

Hook Call Requirements

Hooks can only be called inside the body of a function component. Calling Hooks outside of a React component will result in an error:
Invalid hook call. Hooks can only be called inside of the body of a function component.
This error can happen for these reasons:
  1. Mismatching versions of React and the renderer (e.g., React DOM)
  2. Breaking the Rules of Hooks
  3. Having more than one copy of React in the same app

TypeScript Support

All React Hooks have built-in TypeScript types. You can use generics to specify types:
const [count, setCount] = useState<number>(0);
const [user, setUser] = useState<User | null>(null);
const ref = useRef<HTMLDivElement>(null);

Performance Considerations

  • Hooks don’t add runtime overhead compared to class components
  • State updates are batched automatically in React 18+
  • Use performance hooks like useMemo and useCallback only when needed
  • Don’t optimize prematurely - measure first

Migration from Classes

If you’re migrating from class components:
Class ComponentHook Equivalent
this.stateuseState
this.setStateuseState setter
componentDidMountuseEffect(() => {...}, [])
componentDidUpdateuseEffect(() => {...})
componentWillUnmountuseEffect cleanup function
this.myRefuseRef
Context ConsumeruseContext

Next Steps

  • Start with useState for basic state management
  • Learn useEffect for side effects
  • Explore useContext for prop drilling solutions
  • Dive into performance hooks when needed