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
  }
});

233voto

julen Punkte 4893

Nicht kontrollierte Komponenten

Sie können die event.persist() Methode verwenden.

Ein Beispiel folgt unter Verwendung von Underscore.js' _.debounce():

var SearchBox = React.createClass({

  componentWillMount: function () {
     this.delayedCallback = _.debounce(function (event) {
       // `event.target` is accessible now
     }, 1000);
  },

  onChange: function (event) {
    event.persist();
    this.delayedCallback(event);
  },

  render: function () {
    return (

    );
  }

});

Siehe dieses JSFiddle.


Kontrollierte Komponenten

Das obige Beispiel zeigt eine nicht kontrollierte Komponente. Ich verwende kontrollierte Elemente die ganze Zeit, also hier ist ein weiteres Beispiel des obigen, aber ohne die Verwendung des event.persist() "Tricks".

Ein JSFiddle ist ebenfalls verfügbar. Beispiel ohne Unterstrich

var SearchBox = React.createClass({
    getInitialState: function () {
        return {
            query: this.props.query
        };
    },

    componentWillMount: function () {
       this.handleSearchDebounced = _.debounce(function () {
           this.props.handleSearch.apply(this, [this.state.query]);
       }, 500);
    },

    onChange: function (event) {
      this.setState({query: event.target.value});
      this.handleSearchDebounced();
    },

    render: function () {
      return (

      );
    }
});

var Search = React.createClass({
    getInitialState: function () {
        return {
            result: this.props.query
        };
    },

    handleSearch: function (query) {
        this.setState({result: query});
    },

    render: function () {
      return (

          Sie haben gesucht nach: {this.state.result}

      );
    }
});

React.render(, document.body);

130voto

Sameer Ingavale Punkte 2140

2019: Verwenden des 'useCallback' React Hooks

Nachdem ich viele verschiedene Ansätze ausprobiert habe, habe ich festgestellt, dass die Verwendung von useCallback am einfachsten und effizientesten ist, um das Problem der mehrfachen Aufrufe bei der Verwendung von debounce innerhalb eines onChange Ereignisses zu lösen.

Wie in der Hooks API Dokumentation angegeben,

liefert useCallback eine gespeicherte Version des Callbacks zurück, die sich nur ändert, wenn sich eine der Abhängigkeiten geändert hat.

Das Übergeben eines leeren Arrays als Abhängigkeit stellt sicher, dass der Callback nur einmal aufgerufen wird. Hier ist eine einfache Implementierung :

import React, { useCallback } from "react";
import { debounce } from "lodash";

const handler = useCallback(debounce(someFunction, 2000), []);

const onChange = (event) => {
    // führe hier eine beliebige ereignisbezogene Aktion aus

    handler();
 };

26voto

Hooman Askari Punkte 1287

Nachdem ich eine Weile mit den Texteingaben gekämpft habe und keine perfekte Lösung gefunden habe, habe ich dies auf npm gefunden: react-debounce-input.

Hier ist ein einfaches Beispiel:

import React from 'react';
import ReactDOM from 'react-dom';
import {DebounceInput} from 'react-debounce-input';

class App extends React.Component {
    state = {
        value: ''
    };

    render() {
        return (

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

                Value: {this.state.value}

        );
    }
}

const appRoot = document.createElement('div');
document.body.appendChild(appRoot);
ReactDOM.render(, appRoot);

Das DebounceInput-Komponente akzeptiert alle Eigenschaften, die Sie einem normalen Eingabeelement zuweisen können. Probieren Sie es auf CodePen aus.

21voto

Adam Pietrasiak Punkte 11497

Meine Lösung basiert auf Hooks (geschrieben in TypeScript).

Ich habe zwei Haupt-Hooks useDebouncedValue und useDebouncedCallback

Erstens - useDebouncedValue

Angenommen, wir haben ein Suchfeld, aber wir möchten den Server nach Suchergebnissen fragen, nachdem der Benutzer aufgehört hat zu tippen für 0,5 Sekunden:

function SearchInput() {
  const [realTimeValue, setRealTimeValue] = useState('');

  const debouncedValue = useDebouncedValue(realTimeValue, 500); // dieser Wert wird den Echtzeitwert übernehmen, aber das Ergebnis nur ändern, wenn er sich für 500ms gesetzt hat

  useEffect(() => {
    // dieser Effekt wird bei gesetzten Werten aufgerufen
    api.fetchSearchResults(debouncedValue);
  }, [debouncedValue])

  return  setRealTimeValue(event.target.value)} />
}

Umsetzung

import { useState, useEffect } from "react";

export function useDebouncedValue(input: T, time = 500) {
  const [debouncedValue, setDebouncedValue] = useState(input);

  // Jedes Mal, wenn sich der Eingabewert geändert hat - Intervall setzen, bevor er tatsächlich übernommen wird
  useEffect(() => {
    const timeout = setTimeout(() => {
      setDebouncedValue(input);
    }, time);

    return () => {
      clearTimeout(timeout);
    };
  }, [input, time]);

  return debouncedValue;
}

Zweitens useDebouncedCallback

Es erstellt einfach eine 'gedämpfte' Funktion im Bereich Ihres Components.

Angenommen, wir haben ein Component mit einem Button, der 500 ms nach dem Klicken eine Warnung anzeigen wird:

function AlertButton() {
  function showAlert() {
    alert('Das Klicken hat sich eingestellt');
  }

  const debouncedShowAlert = useDebouncedCallback(showAlert, 500);

  return Klicken
}

Umsetzung (beachten Sie, dass ich Lodash/debounce als Hilfsmittel verwende)

import debounce from 'lodash/debounce';
import { useMemo } from 'react';

export function useDebouncedCallback any>(callback: T, wait?: number) {
  const debouncedCallback = useMemo(() => debounce(callback, wait), [callback, wait]);

  return debouncedCallback;
}

21voto

Ashutosh Tripathi Punkte 281

Es kann einen einfachen Ansatz geben, der React-Hooks verwendet.

Schritt 1: Definieren Sie einen Zustand, um den gesuchten Text zu speichern

const [searchTerm, setSearchTerm] = useState('')

Schritt 2: Verwenden Sie useEffect, um Änderungen in searchTerm zu erfassen

useEffect(() => {
  const delayDebounceFn = setTimeout(() => {
    if (searchTerm) {
      // Schreiben Sie hier Ihre Logik
    }
  }, 400)

  return () => clearTimeout(delayDebounceFn)
}, [searchTerm])

Schritt 3: Schreiben Sie eine Funktion, um die Eingabeänderung zu behandeln

Funktion handleInputChange(value) {
  if (value) {
    setSearchTerm(value)
  }
}

Das ist alles! Rufen Sie diese Methode nach Bedarf auf.

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