DEV Community

Cover image for Essential React Hooks & Practical Use Cases 🎣
saida lachgar
saida lachgar

Posted on β€’ Originally published at saidalachgar.dev

Essential React Hooks & Practical Use Cases 🎣

What Are React Hooks?

Functions that let you use React features in functional components without classes.

7 Essential Hooks

1. useState

What it does: keeps track of values that can change in your app

// e.g. 1: Basic state management
const [count, setCount] = useState(0);

// e.g. 2: Form inputs
const [name, setName] = useState('');
Enter fullscreen mode Exit fullscreen mode

When to use:

  • Storing form input values
  • Toggling UI states (open/closed)
  • Tracking simple values (counters, flags)

2. useEffect

What it does: helps us run code when things change (or when a component first loads)

// e.g. 1: Run once on mount (empty dependencies)
useEffect(() => {
  // Setup code
  return () => { /* Cleanup code */ };
}, []);

// e.g. 2: Run when dependencies change
useEffect(() => {
  document.title = `${count} new messages`;
}, [count]);
Enter fullscreen mode Exit fullscreen mode

When to use:

  • Data fetching
  • Subscriptions/event listeners
  • DOM manipulation
  • Syncing with external systems

3. useContext

What it does: allows multiple components to share the same data without passing it manually

// Access theme from anywhere in component tree
const theme = useContext(ThemeContext);
Enter fullscreen mode Exit fullscreen mode

When to use:

  • Accessing global state (themes, user data)
  • Avoiding prop drilling through many components
  • When multiple components need the same data

4. useRef

What it does: helps reference an element without causing unnecessary re-renders

// e.g. 1: DOM element reference
const inputRef = useRef(null);
inputRef.current.focus();

// e.g. 2: Value persistence between renders
const prevCountRef = useRef();
Enter fullscreen mode Exit fullscreen mode

When to use:

  • Accessing DOM elements
  • Storing previous values
  • Holding values that shouldn't trigger re-renders
  • Managing timers/intervals

5. useReducer

What it does: Manages complex state logic

const [state, dispatch] = useReducer(reducer, initialState);
dispatch({ type: 'increment' });
Enter fullscreen mode Exit fullscreen mode

When to use:

  • Complex state with multiple sub-values
  • When next state depends on previous state
  • When state transitions have business logic
  • When actions cause multiple state updates

6. useMemo

What it does: expensive calculations to avoid recomputing them unnecessarily

const expensiveValue = useMemo(() => {
  return computeExpensiveValue(data);
}, [data]);
Enter fullscreen mode Exit fullscreen mode

When to use:

  • Optimizing performance-heavy calculations
  • Preventing unnecessary computations

7. useCallback

What it does: Memoizes functions so they don’t get recreated every render

const handleClick = useCallback(() => {
  console.log('Clicked!');
}, []);
Enter fullscreen mode Exit fullscreen mode

When to use:

  • Preventing unnecessary re-renders in child components
  • Avoiding function recreation on every render

Custom Hooks

Create your own hooks to reuse logic between components:

// Extract reusable logic
function useWindowSize() {
  const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight });

  // Event handling + cleanup in one hook
  useEffect(() => {
    const handleResize = () => setSize({ width: window.innerWidth, height: window.innerHeight });
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return size;
}
Enter fullscreen mode Exit fullscreen mode

Rules of Hooks

  1. Only call at top level (no conditions/loops)
  2. Only call from React functions
  3. Name custom hooks with "use" prefix

Quick Tips

  • Use useState for simple state, useReducer for complex state
  • Don't forget cleanup functions in useEffect
  • Optimize renders with useMemo and useCallback
  • Create custom hooks to share logic, not just for reuse
  • Use useImperativeHandle to expose methods from child components to parents.
  • Use useLayoutEffect when updates need to happen before the browser paints.
  • Use useDebugValue to add labels to custom hooks for easier debugging in React DevTools.

πŸš€ Wrapping Up

React Hooks are powerful and fun when you understand how they work! Here's a quick recap:

βœ… useState β†’ Keeps track of changing values (Think of useState as a small whiteboard where you can jot down notes Β«dataΒ» that might change over time)
βœ… useEffect β†’ Runs side effects (like setting a reminder alarm. When certain things happen, you want to be reminded to do something)
βœ… useContext β†’ Shares values across components (Imagine a family chalkboard in your house where everyone can read and write messages)
βœ… useRef β†’ References elements without re-rendering (is like placing a bookmark in a book. It helps you keep track of a specific spot or element)
βœ… useReducer β†’ Handles complex state logic (like a suggestion box for managing complex state changes)
βœ… useMemo β†’ Optimizes calculations (like a chef who prepares ingredients in advance so they don’t have to chop them again for every order)
βœ… useCallback β†’ Optimizes functions (like saving a shopping list so you don’t rewrite it every time you go shopping!)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free β†’

πŸ‘‹ Kindness is contagious

Please leave a ❀️ or a friendly comment on this post if you found it helpful!

Okay