← Back to Guides
React

Complete Guide to React Hooks

react hooks javascript

React Hooks revolutionized how we write React components. This guide will walk you through all the essential hooks and when to use them.

useState - Managing State

The most basic hook for managing component state:

import { useState } from 'react';
 
function Counter() {
  const [count, setCount] = useState(0);
 
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
}

useEffect - Side Effects

Handle side effects like data fetching, subscriptions, and DOM manipulation:

import { useEffect, useState } from 'react';
 
function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
 
  useEffect(() => {
    async function fetchUser() {
      const response = await fetch(`/api/users/${userId}`);
      const data = await response.json();
      setUser(data);
    }
 
    fetchUser();
  }, [userId]);
 
  return <div>{user?.name}</div>;
}

useContext - Consuming Context

Access context values without prop drilling:

import { useContext } from 'react';
import { ThemeContext } from './ThemeContext';
 
function ThemedButton() {
  const theme = useContext(ThemeContext);
 
  return (
    <button style={{ background: theme.background }}>
      Themed Button
    </button>
  );
}

useCallback and useMemo

Optimize performance by memoizing functions and values:

import { useCallback, useMemo } from 'react';
 
function ExpensiveComponent({ items, onItemClick }) {
  const sortedItems = useMemo(() => {
    return [...items].sort((a, b) => a.name.localeCompare(b.name));
  }, [items]);
 
  const handleClick = useCallback((item) => {
    onItemClick(item);
  }, [onItemClick]);
 
  return (
    <ul>
      {sortedItems.map(item => (
        <li key={item.id} onClick={() => handleClick(item)}>
          {item.name}
        </li>
      ))}
    </ul>
  );
}

Custom Hooks

Create reusable logic by building custom hooks:

function useLocalStorage(key, initialValue) {
  const [value, setValue] = useState(() => {
    const stored = localStorage.getItem(key);
    return stored ? JSON.parse(stored) : initialValue;
  });
 
  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);
 
  return [value, setValue];
}
 
function App() {
  const [name, setName] = useLocalStorage('name', '');
 
  return (
    <input
      value={name}
      onChange={(e) => setName(e.target.value)}
    />
  );
}

Best Practices

  1. Always follow the Rules of Hooks: Call hooks at the top level, not inside conditions or loops
  2. Use ESLint plugin: Install eslint-plugin-react-hooks to catch mistakes
  3. Keep effects focused: Split multiple concerns into separate useEffect calls
  4. Memoize carefully: Don’t over-optimize with useMemo and useCallback

Conclusion

React Hooks provide a powerful way to write clean, reusable component logic. Master these patterns and your React code will be more maintainable and easier to understand.