Home >Web Front-end >JS Tutorial >How to Implement Debouncing in React Applications?

How to Implement Debouncing in React Applications?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-12-05 19:18:11279browse

How to Implement Debouncing in React Applications?

How do I perform debounce in React?

React owes its popularity to its component-based architecture. Often, we have components that listen to input changes and trigger API calls to retrieve data. We want to debounce these API calls to avoid making unnecessary requests.

debounce with React hooks and Suspense

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

const debounce = (fn, delay) => {
  let timeoutId;
  return (...args) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => {
      fn(...args);
    }, delay);
  };
};

const SearchBox = () => {
  const [inputText, setInputText] = useState('');
  const [searchResults, setSearchResults] = useState(null);

  const fetchResults = async (text) => {
    const response = await fetch(`/search?text=${text}`);
    const data = await response.json();
    setSearchResults(data);
  };

  const debouncedFetchResults = debounce(fetchResults, 500);

  useEffect(() => {
    if (!inputText) {
      return;
    }
    debouncedFetchResults(inputText);
  }, [inputText, debouncedFetchResults]);

  return (
    <>
      <input type="search" value={inputText} onChange={(e) => setInputText(e.target.value)} />
      <Suspense fallback={<div>Loading...</div>}>
        {searchResults && <Results results={searchResults} />}
      </Suspense>
    </>
  );
};

In this example, we use the debounce function to wrap the fetchResults function and only make the API call after 500ms of inactivity. We debounce the function on every change of the inputText state. We then use Suspense to render a placeholder while the results are being fetched.

Debounce with class components

Although React hooks are encouraged, you could also use class components to debounce:

import React, { Component } from 'react';

const debounce = (fn, delay) => {
  let timeoutId;
  return (...args) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => {
      fn(...args);
    }, delay);
  };
};

class SearchBox extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inputText: '',
      searchResults: null
    };
    this.debouncedFetchResults = debounce(this.fetchResults, 500);
  }

  fetchResults = async (text) => {
    const response = await fetch(`/search?text=${text}`);
    const data = await response.json();
    this.setState({ searchResults: data });
  };

  handleInputChange = (e) => {
    const text = e.target.value;
    this.setState({ inputText: text });
    this.debouncedFetchResults(text);
  };

  render() {
    return (
      <>
        <input type="search" value={this.state.inputText} onChange={this.handleInputChange} />
        {this.state.searchResults && <Results results={this.state.searchResults} />}
      </>
    );
  }
}

Debounce with event pooling

When attaching event handlers in React, remember that event objects are pooled to reduce GC pressure. If you want to access event properties asynchronously to the handler call, you can use the e.persist() method to prevent the event from being returned to the pool:

const onClick = (e) => {
  e.persist(); // Prevent the event object from being returned to the pool
  setTimeout(() => {
    // Access event properties here
  }, 0);
};

<button onClick={onClick}>Click Me</button>

The above is the detailed content of How to Implement Debouncing in React Applications?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn