DEV Community

Abhinav
Abhinav

Posted on

React Hooks: The Must-Use Hooks You Need to Know πŸ’‘

React hooks have transformed the way developers build and manage components. By providing a clean, functional way to handle state, side effects, and other features, hooks have become an essential part of modern React development. In this blog, we’ll explore the most commonly used hooks every React developer should master, along with practical examples to demonstrate their real-world applications.


Index πŸ“–

  1. useState πŸ“Š
  2. useEffect ⌚
  3. useContext πŸ”
  4. useRef πŸ”„
  5. useReducer πŸ”„
  6. useMemo 🎨
  7. useCallback πŸ”

1. useState πŸ“Š

The useState hook is the cornerstone of managing state in functional components. It allows you to add and update local state in a simple, declarative manner.

Example: Counter Component with Local Storage

import React, { useState, useEffect } from 'react';

function Counter() {
  const [count, setCount] = useState(() => {
    const saved = localStorage.getItem('count');
    return saved ? parseInt(saved, 10) : 0;
  });

  useEffect(() => {
    localStorage.setItem('count', count);
  }, [count]);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
  • Why use it? Integrates seamlessly with persistent storage, making it ideal for saving user progress.

2. useEffect ⌚

The useEffect hook is a powerful way to handle side effects like fetching data, subscribing to events, or updating the DOM. It replaces lifecycle methods like componentDidMount, componentDidUpdate, and componentWillUnmount.

Example: Polling API Data

import React, { useEffect, useState } from 'react';

function LiveScores() {
  const [scores, setScores] = useState([]);

  useEffect(() => {
    const interval = setInterval(() => {
      fetch('https://api.example.com/scores')
        .then(response => response.json())
        .then(data => setScores(data));
    }, 5000);

    return () => clearInterval(interval); // Cleanup on unmount
  }, []);

  return (
    <ul>
      {scores.map(score => (
        <li key={score.id}>{score.team}: {score.points}</li>
      ))}
    </ul>
  );
}
Enter fullscreen mode Exit fullscreen mode
  • Why use it? Efficiently manages periodic updates for real-time applications.

3. useContext πŸ”

The useContext hook provides a way to access context values directly in functional components without the need for Context.Consumer wrappers.

Example: User Authentication

import React, { useContext } from 'react';
import { AuthContext } from './AuthProvider';

function UserProfile() {
  const { user } = useContext(AuthContext);

  return (
    <div>
      <h1>Welcome, {user.name}!</h1>
      <p>Email: {user.email}</p>
    </div>
  );
}

function App() {
  const user = { name: 'Taylor', email: 'taylor@example.com' };

  return (
    <AuthContext.Provider value={{ user }}>
      <UserProfile />
    </AuthContext.Provider>
  );
}
Enter fullscreen mode Exit fullscreen mode
  • Why use it? Great for managing user sessions and other global state.

4. useRef πŸ”„

The useRef hook provides a way to persist values across renders without causing re-renders. It’s often used to access DOM elements or store mutable values.

Example: Debouncing Input

import React, { useRef, useState } from 'react';

function SearchBar({ onSearch }) {
  const [query, setQuery] = useState('');
  const timeoutRef = useRef(null);

  const handleChange = (e) => {
    const value = e.target.value;
    setQuery(value);

    if (timeoutRef.current) clearTimeout(timeoutRef.current);

    timeoutRef.current = setTimeout(() => {
      onSearch(value);
    }, 500); // Debounce time
  };

  return <input type="text" value={query} onChange={handleChange} />;
}
Enter fullscreen mode Exit fullscreen mode
  • Why use it? Optimizes performance in search or real-time filtering scenarios.

5. useReducer πŸ”„

The useReducer hook is an alternative to useState when state management becomes more complex. It’s particularly useful for managing state with multiple actions.

Example: Shopping Cart

import React, { useReducer } from 'react';

function cartReducer(state, action) {
  switch (action.type) {
    case 'add':
      return [...state, action.item];
    case 'remove':
      return state.filter(item => item.id !== action.id);
    default:
      throw new Error('Unknown action');
  }
}

function Cart() {
  const [cart, dispatch] = useReducer(cartReducer, []);

  const addItem = (item) => dispatch({ type: 'add', item });
  const removeItem = (id) => dispatch({ type: 'remove', id });

  return (
    <div>
      <h1>Shopping Cart</h1>
      <ul>
        {cart.map(item => (
          <li key={item.id}>
            {item.name} <button onClick={() => removeItem(item.id)}>Remove</button>
          </li>
        ))}
      </ul>
      <button onClick={() => addItem({ id: 1, name: 'Apple' })}>Add Apple</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
  • Why use it? Handles complex state transitions cleanly in e-commerce or form-heavy apps.

6. useMemo 🎨

The useMemo hook helps optimize performance by memoizing expensive computations. It recomputes the value only when dependencies change.

Example: Filtering Large Data

import React, { useMemo, useState } from 'react';

function LargeList({ items }) {
  const [query, setQuery] = useState('');

  const filteredItems = useMemo(() => {
    return items.filter(item => item.includes(query));
  }, [items, query]);

  return (
    <div>
      <input
        type="text"
        placeholder="Search..."
        value={query}
        onChange={(e) => setQuery(e.target.value)}
      />
      <ul>
        {filteredItems.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
  • Why use it? Boosts performance for lists or tables with thousands of rows.

7. useCallback πŸ”

The useCallback hook memoizes callback functions to avoid unnecessary re-creation on every render. It’s especially useful when passing callbacks to child components.

Example: Optimized Child Rendering

import React, { useState, useCallback } from 'react';

function Child({ onClick }) {
  console.log('Child rendered');
  return <button onClick={onClick}>Click Me</button>;
}

function Parent() {
  const [count, setCount] = useState(0);

  const increment = useCallback(() => setCount((prev) => prev + 1), []);

  return (
    <div>
      <p>Count: {count}</p>
      <Child onClick={increment} />
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
  • Why use it? Prevents performance bottlenecks by minimizing child re-renders.

Conclusion 🎯

React hooks provide powerful tools for managing state, side effects, performance optimizations, and more. Mastering these hooksβ€”useState, useEffect, useContext, useRef, useReducer, useMemo, and useCallbackβ€”will enable you to write cleaner, more efficient React applications.

Start incorporating these hooks into your projects and watch your React skills elevate to the next level!

Top comments (0)