Open In App

How to use Debouncing and Throttling with React Hooks ?

In React applications, managing user input effectively is crucial for creating a smooth and responsive user experience. Two common techniques for handling user input efficiently are debouncing and throttling. In this article, we'll explore how to implement debouncing and throttling in React using hooks, with easy-to-understand examples. We'll also incorporate the JSON Placeholder API to demonstrate real-world usage scenarios.

Prerequisites:

Understanding Debouncing and Throttling:

Debouncing and throttling are both strategies to control the rate at which a function is executed in response to repeated events, such as user input.

Different use cases:

Throttling:

Debouncing:

Implementing Debouncing and Throttling with React Hooks:

Let's consider a scenario where we have a search input field in a React component that fetches data from the JSON Placeholder API as the user types. We'll use debouncing to delay the API request until the user pauses typing and throttling to limit the frequency of API requests.

This component allows users to:

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

const SearchComponent = () => {
    const [query, setQuery] = useState('');
    const [results, setResults] = useState([]);
    const [loading, setLoading] = useState(false);
    const [isThrottling, setIsThrottling] = useState(false);
    const [inputStatus, setInputStatus] = 
                                    useState('Waiting for input...');

    // Debounce function
    const debounce = (func, delay) => {
        let timer;
        return (...args) => {
            clearTimeout(timer);
            timer = setTimeout(() => {
                func(...args);
            }, delay);
        };
    };

    // Throttle function
    const throttle = (func, delay) => {
        let lastCall = 0;
        return (...args) => {
            const now = new Date().getTime();
            if (now - lastCall < delay) {
                return;
            }
            lastCall = now;
            func(...args);
        };
    };

    useEffect(() => {
        const fetchData = async () => {
            if (!query) {
                setResults([]);
                setLoading(false);
                return;
            }
            setLoading(true);
            try {
                const response = await axios.get(`
https://jsonplaceholder.typicode.com/posts?title_like=${query}`);
                setResults(response.data);
                setLoading(false);
            } catch (error) {
                console.error('Error fetching data:', error);
                setLoading(false);
            }
        };

        const debouncedFetch = debounce(fetchData, 500);
        const throttledFetch = throttle(fetchData, 1000);

        if (isThrottling) {
            throttledFetch();
            setInputStatus('Throttling...');
        } else {
            debouncedFetch();
            setInputStatus('Debouncing...');
        }

        const timer = setTimeout(() => {
            setInputStatus('Waiting for input...');
        }, isThrottling ? 1000 : 500);

        return () => clearTimeout(timer);
    }, [query, isThrottling]);

    return (
        <div>
            <label>
                Toggle Throttling/Debouncing:
                <input
                    type="checkbox"
                    checked={isThrottling}
                    onChange={() => setIsThrottling(!isThrottling)}
                />
            </label>
            <input
                type="text"
                placeholder="Search..."
                value={query}
                onChange={(e) => setQuery(e.target.value)}
            />
            <p>{inputStatus}</p>
            {
                loading ?
                    <p>Loading...</p> :
                    <ul>{results.map((result) =>
                        <li key={result.id}>{result.title}</li>
                    )}
                    </ul>
            }
        </div>
    );
};

export default SearchComponent;

Output:

Untitled-design-(36)

Output

Conclusion:

Debouncing and throttling are powerful techniques for managing user input and optimizing API requests in React applications. By incorporating these strategies with React hooks, we can create more efficient and responsive user interfaces. With the easy-to-understand example provided in this article, even beginners can grasp the concept of debouncing and throttling and apply them to their React projects.

Article Tags :