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

0voto

Dies ist der sauberste Weg, den ich gefunden habe, um Debouncing zu realisieren. Ich weiß, dass es ähnliche Antworten gibt, aber ich möchte die Grundidee dokumentieren, damit sie jeder in der Zukunft erfassen und in seinen Code integrieren kann.

let timer = null;
function debouce(func) {
  clearTimeout(timer);
  timer = setTimeout(() => {
    func();
  }, 1000);
}

// simulate frequent calls
debouce(()=> console.log("Anruf 1"));
debouce(()=> console.log("Anruf 2"));
debouce(()=> console.log("Anruf 3"));

// simulate future call
setTimeout(() => {
  debouce(()=> console.log("Anruf 4"));
}, 2000);

0voto

srcspider Punkte 10579

Julens Lösung ist irgendwie schwer zu lesen. Hier ist klarerer und auf den Punkt gebrachter React-Code für jeden, der auf diese Antwort gestoßen ist, basierend auf dem Titel und nicht auf den winzigen Details der Frage.

tl;dr Version: Wenn Sie Aktualisierungen an Beobachter senden würden, rufen Sie stattdessen eine Schedule-Methode auf, die die Beobachter tatsächlich benachrichtigt (oder Ajax ausführt usw.).

Vollständiger jsfiddle mit Beispiel-Komponente jsfiddle

var InputField = React.createClass({

    getDefaultProps: function () {
        return {
            initialValue: '',
            onChange: null
        };
    },

    getInitialState: function () {
        return {
            value: this.props.initialValue
        };
    },

    render: function () {
        var state = this.state;
        return (

        );
    },

    onVolatileChange: function (event) {
        this.setState({ 
            value: event.target.value 
        });

        this.scheduleChange();
    },

    scheduleChange: _.debounce(function () {
        this.onChange();
    }, 250),

    onChange: function () {
        var props = this.props;
        if (props.onChange != null) {
            props.onChange.call(this, this.state.value)
        }
    },

});

0voto

Aakash Punkte 17068

Wir müssten den setter an die gedrosselte Methode übergeben:

Hier ist ein Ausschnitt aus einem Beispiel auf StackBlitz:

import React from "react";
import debounce from "lodash/debounce";

export default function App() {
  const [state, setState] = React.useState({
    debouncedLog: ""
  });

  const debouncedLog = React.useCallback(
    debounce((setState, log) => {
      setState(prevState => ({
        ...prevState,
        debouncedLog: log
      }));
    }, 500),
    []
  );

  const onChange = React.useCallback(({ target: { value: log } }) => {
    debouncedLog(setState, log); // den setState weitergeben...
  }, []);
  return (

      Debounced-Wert: {state.debouncedLog}

  );
}

Viel Glück...

0voto

Micah B. Punkte 1018

Erweitere den useState Hook

import { useState } from "react";
import _ from "underscore"
export const useDebouncedState = (initialState, durationInMs = 500) => {
    const [internalState, setInternalState] = useState(initialState);
    const debouncedFunction = _.debounce(setInternalState, durationInMs);
    return [internalState, debouncedFunction];
};
export default useDebouncedState;

Verwende den Hook

import useDebouncedState from "../hooks/useDebouncedState"
//...
const [usernameFilter, setUsernameFilter] = useDebouncedState("")
//...
 setUsernameFilter(e.target.value)}>

https://trippingoncode.com/react-debounce-hook/

0voto

Dominic Punkte 55062

Vermeiden Sie die Verwendung von event.persist() - Sie möchten, dass React das synthetische Ereignis recyclt. Ich denke, der sauberste Weg, ob Sie Klassen oder Hooks verwenden, ist das Aufteilen des Rückrufs in zwei Teile:

  1. Der Rückruf ohne Debouncing
  2. Ruft eine gedeischte Funktion mit nur den Teilen des Ereignisses auf, die Sie benötigen (damit das synthetische Ereignis recycelt werden kann)

Klassen

handleMouseOver = throttle(target => {
  console.log(target);
}, 1000);

onMouseOver = e => {
  this.handleMouseOver(e.target);
};

Funktionen

const handleMouseOver = useRef(throttle(target => {
  console.log(target);
}, 1000));

function onMouseOver(e) {
  handleMouseOver.current(e.target);
}

Beachten Sie, dass, wenn Ihre handleMouseOver-Funktion den Zustand innerhalb des Components verwendet, sollten Sie useMemo anstelle von useRef verwenden und dies als Abhängigkeiten übergeben, sonst arbeiten Sie mit veralteten Daten (gilt natürlich nicht für Klassen).

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