690 Stimmen

Wie kann ich ein Debounce durchführen?

Wie führen Sie eine Verzögerung in React durch?

Ich möchte die Funktion handleOnChange verzögern.

Ich habe es mit debounce(this.handleOnChange, 200) versucht, aber es funktioniert nicht.

function debounce(fn, delay) {
  var timer = null;
  return function() {
    var context = this,
      args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  };
}

var SearchBox = React.createClass({
  render: function() {
    return ;
  },

  handleOnChange: function(event) {
    // Führen Sie Ajax-Aufruf durch
  }
});

6voto

Or Assayag Punkte 4220

Stand Juni 2021 können Sie einfach die Lösung von xnimorz implementieren: use-debounce

import { useState, useEffect, useRef } from "react";
// Verwendung
function App() {
  // Zustand und Setter für ...
  // Suchbegriff
  const [searchTerm, setSearchTerm] = useState("");
  // API Suchergebnisse
  const [results, setResults] = useState([]);
  // Suchstatus (ob eine ausstehende API-Anfrage vorliegt)
  const [isSearching, setIsSearching] = useState(false);
  // Verzögerung des Suchbegriffs, damit nur der neueste Wert geliefert wird ...
  // ... wenn der Suchbegriff in den letzten 500 ms nicht aktualisiert wurde.
  // Das Ziel ist es, den API-Aufruf nur auszulösen, wenn der Benutzer aufhört zu tippen ...
  // ... damit wir unsere API nicht zu schnell abfragen.
  const debouncedSearchTerm = useDebounce(searchTerm, 500);
  // Effekt für API-Aufruf
  useEffect(
    () => {
      if (debouncedSearchTerm) {
        setIsSearching(true);
        searchCharacters(debouncedSearchTerm).then((results) => {
          setIsSearching(false);
          setResults(results);
        });
      } else {
        setResults([]);
        setIsSearching(false);
      }
    },
    [debouncedSearchTerm] // Effekt nur aufrufen, wenn sich der verzögerte Suchbegriff ändert
  );
  return (

       setSearchTerm(e.target.value)}
      />
      {isSearching && Suche ...}
      {results.map((result) => (

          {result.title}

      ))}

  );
}
// API Suchfunktion
function searchCharacters(search) {
  const apiKey = "f9dfb1e8d466d36c27850bedd2047687";
  return fetch(
    `https://gateway.marvel.com/v1/public/comics?apikey=${apiKey}&titleStartsWith=${search}`,
    {
      method: "GET",
    }
  )
    .then((r) => r.json())
    .then((r) => r.data.results)
    .catch((error) => {
      console.error(error);
      return [];
    });
}
// Hook
function useDebounce(value, delay) {
  // Zustand und Setter für den verzögerten Wert
  const [debouncedValue, setDebouncedValue] = useState(value);
  useEffect(
    () => {
      // Verzögerten Wert nach Verzögerung aktualisieren
      const handler = setTimeout(() => {
        setDebouncedValue(value);
      }, delay);
      // Timeout abbrechen, wenn der Wert geändert wird (auch bei Änderung der Verzögerung oder Demontage)
      // So verhindern wir, dass der verzögerte Wert aktualisiert wird, wenn der Wert geändert wird ...
      // .. innerhalb des Verzögerungszeitraums. Timeout wird gelöscht und neu gestartet.
      return () => {
        clearTimeout(handler);
      };
    },
    [value, delay] // Effekt nur erneut aufrufen, wenn sich Wert oder Verzögerung ändern
  );
  return debouncedValue;
}

6voto

Xinan Punkte 2963

Ich kann keine Antworten zu dieser Frage finden, die den Ansatz erwähnen, den ich verwende. Daher möchte ich einfach hier eine alternative Lösung anbieten, die meiner Meinung nach am besten für meinen Anwendungsfall geeignet ist.

Wenn Sie die beliebte React Hooks-Toolkit-Bibliothek namens react-use verwenden, gibt es einen Hilfshaken namens useDebounce(), der die verzögerte Logik auf eine ziemlich elegante Weise implementiert.

const [query, setQuery] = useState('');

useDebounce(
  () => {
    emitYourOnDebouncedSearchEvent(query);
  },
  2000,
  [query]
);

return  setQuery(currentTarget.value)} />

Weitere Details finden Sie direkt auf der GitHub-Seite der Bibliothek.

6voto

Rebs Punkte 253

Es gibt jetzt eine weitere Lösung für React und React Native im späten Jahr 2019:

react-debounce-component

Es ist eine Komponente, einfach zu bedienen, winzig und weit verbreitet

Beispiel:

Bildbeschreibung hier eingeben

import React from 'react';
import Debounce from 'react-debounce-component';

class App extends React.Component {
  constructor (props) {
    super(props);
    this.state = {value: 'Hallo'}
  }
  render () {
    return (

         {this.setState({value: event.target.value})}}/>

          {this.state.value}

    );
  }
}

export default App;

*Ich bin der Ersteller dieser Komponente

5voto

Bruno Silvano Punkte 274

Eine schöne und saubere Lösung, die keine externen Abhängigkeiten erfordert:

Debouncing mit React Hooks

Es verwendet benutzerdefinierte plus die useEffect React Hooks und die setTimeout / clearTimeout Methode.

4voto

puchu Punkte 2963

Nur eine weitere Variante mit kürzlichem React und Lodash.

class Filter extends Component {
  static propTypes = {
    text: PropTypes.string.isRequired,
    onChange: PropTypes.func.isRequired
  }

  state = {
    initialText: '',
    text: ''
  }

  constructor (props) {
    super(props)

    this.setText = this.setText.bind(this)
    this.onChange = _.fp.debounce(500)(this.onChange.bind(this))
  }

  static getDerivedStateFromProps (nextProps, prevState) {
    const { text } = nextProps

    if (text !== prevState.initialText) {
      return { initialText: text, text }
    }

    return null
  }

  setText (text) {
    this.setState({ text })
    this.onChange(text)
  }

  onChange (text) {
    this.props.onChange(text)
  }

  render () {
    return ( this.setText(event.target.value)} />)
  }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X