</>
Skip to content
React lessons (24/47)

React — useCallback

Basic useCallback

import { useCallback } from 'react';

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

    const increment = useCallback(() => {
        setCount(c => c + 1);
    }, []);

    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={increment}>Increment</button>
        </div>
    );
}

useCallback with Dependencies

function Search({ onSearch }) {
    const [query, setQuery] = useState('');

    const handleSearch = useCallback(() => {
        onSearch(query);
    }, [query, onSearch]);

    return (
        <div>
            <input
                value={query}
                onChange={(e) => setQuery(e.target.value)}
            />
            <button onClick={handleSearch}>Search</button>
        </div>
    );
}

useCallback with Child Components

// Expensive child component
const ExpensiveChild = React.memo(({ onClick }) => {
    console.log('ExpensiveChild rendered');
    return <button onClick={onClick}>Click me</button>;
});

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

    // Without useCallback - child re-renders every time
    const handleClick = () => {
        console.log('Clicked');
    };

    // With useCallback - child only re-renders when dependencies change
    const handleClick = useCallback(() => {
        console.log('Clicked');
    }, []);

    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={() => setCount(c => c + 1)}>Increment</button>
            <ExpensiveChild onClick={handleClick} />
        </div>
    );
}

useCallback Examples

// Form submission
function Form({ onSubmit }) {
    const [name, setName] = useState('');
    const [email, setEmail] = useState('');

    const handleSubmit = useCallback((e) => {
        e.preventDefault();
        onSubmit({ name, email });
    }, [name, email, onSubmit]);

    return (
        <form onSubmit={handleSubmit}>
            <input value={name} onChange={(e) => setName(e.target.value)} />
            <input value={email} onChange={(e) => setEmail(e.target.value)} />
            <button type="submit">Submit</button>
        </form>
    );
}

// Todo list with memoized callbacks
function TodoList() {
    const [todos, setTodos] = useState([]);

    const addTodo = useCallback((text) => {
        setTodos(prev => [...prev, { id: Date.now(), text }]);
    }, []);

    const removeTodo = useCallback((id) => {
        setTodos(prev => prev.filter(todo => todo.id !== id));
    }, []);

    return (
        <div>
            <AddTodo onAdd={addTodo} />
            <ul>
                {todos.map(todo => (
                    <TodoItem
                        key={todo.id}
                        todo={todo}
                        onRemove={removeTodo}
                    />
                ))}
            </ul>
        </div>
    );
}

Mini Practice

Write React code that:

  1. Uses useCallback for memoized functions
  2. Passes memoized callbacks to child components
  3. Optimizes performance with useCallback
  4. Compares useCallback with useMemo

Up Next

Next: Learn about Custom Hooks.

Related Topics

Frequently Asked Questions about useCallback

What is useCallback in React?

useCallback is a fundamental concept in React. This lesson explains it step by step with clear examples, making it easy for beginners to understand.

How do I learn useCallback?

Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn useCallback.

Why is useCallback important in React?

useCallback is essential for React development. Understanding this concept will help you write better code and solve real-world problems more effectively.