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

1voto

Edward Punkte 41

Ich habe nach einer Lösung für dasselbe Problem gesucht und bin auf diesen Thread und einige andere gestoßen, die jedoch dasselbe Problem hatten: Wenn Sie versuchen, eine handleOnChange Funktion auszuführen und den Wert aus einem Ereignisziel benötigen, erhalten Sie die Fehlermeldung kann die Eigenschaft value von null nicht lesen oder einen ähnlichen Fehler. In meinem Fall musste ich auch den Kontext von this in der gedeckelten Funktion beibehalten, da ich eine Fluxible-Aktion ausführe. Hier ist meine Lösung, sie funktioniert gut für meinen Anwendungsfall, also lasse ich sie hier, falls jemand auf diesen Thread stößt:

// am Anfang der Datei:
var meineAktion = require('../actions/someAction');

// innerhalb von React.createClass({...});

handleOnChange: function (event) {
    var wert = event.target.value;
    var doAction = _.curry(this.context.executeAction, 2);

    // nur ein Parameter wird in die gedeckelte Funktion übergeben,
    // sodass die als erster Parameter an _.curry() übergebene Funktion 
    // erst dann ausgeführt wird, wenn der zweite Parameter übergeben wird
    // was im nächsten Funktion geschieht, die in _.debounce() eingewickelt ist
    debouncedOnChange(doAction(meineAktion), wert);
},

debouncedOnChange: _.debounce(function(aktion, wert) {
    aktion(wert);
}, 300)

1voto

Ievgen Punkte 3902

React Ajax debounce und Stornierung Beispiel Lösung mit React Hooks und reaktiver Programmierung (RxJS):

import React, { useEffect, useState } from "react";
import { ajax } from "rxjs/ajax";
import { debounceTime, delay, takeUntil } from "rxjs/operators";
import { Subject } from "rxjs/internal/Subject";

const App = () => {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(true);
  const [filterChangedSubject] = useState(() => {
    // Pfeilfunktion wird verwendet, um Singleton-Subject (im Bereich eines aktuellen Komponenten) zu initialisieren
    return new Subject();
  });

  useEffect(() => {
    // Effekt, der einmal bei der Initialisierung einer React-Komponente initialisiert wird.
    const subscription = filterChangedSubject
      .pipe(debounceTime(200))
      .subscribe((filter) => {
        if (!filter) {
          setLoading(false);
          setItems([]);
          return;
        }
        ajax(`https://swapi.dev/api/people?search=${filter}`)
          .pipe(
            // Aktuell laufende Ajax-Anfrage wird bei Filteränderung storniert.
            takeUntil(filterChangedSubject)
          )
          .subscribe(
            (results) => {
              // Setzen von Items wird ein Rendern verursachen:
              setItems(results.response.results);
            },
            () => {
              setLoading(false);
            },
            () => {
              setLoading(false);
            }
          );
      });

    return () => {
      // Bei der Zerstörung der Komponente. Mitteilen von takeUntil, sich von der aktuellen laufenden Ajax-Anfrage abzumelden
      filterChangedSubject.next("");
      // Filteränderungslistener abmelden
      subscription.unsubscribe();
    };
  }, []);

  const onFilterChange = (e) => {
    // Subject über die Filteränderung informieren
    filterChangedSubject.next(e.target.value);
  };
  return (

      Karten
      {loading && Laden...}

      {items && items.map((item, index) => {item.name})}

  );
};

export default App;

1voto

Vince Punkte 676

Wenn Sie nur ein Debounce in einem Button benötigen, um Daten anzufordern, könnte der bereitgestellte Code für Sie hilfreich sein:

  1. Erstellen Sie eine Funktion, um das Standardverhalten mit einer bedingten Anweisung zu verhindern, wenn die Anforderung wahr oder falsch ist

  2. Implementieren Sie den useState Hook und den useEffect Hook

    const PageOne = () => {
     const [requesting, setRequesting] = useState(false);
    
      useEffect(() => {
        return () => {
          setRequesting(false);
        };
      }, [requesting]);
    
      const onDebounce = (e) => {
        if (requesting === true) {
          e.preventDefault();
        }
        // AKTIONEN
        setLoading(true);
      };
    
     return (
    
        Daten anfordern
    
     )
    }

0voto

Himanshu Tariyal Punkte 224

Sie können eine Referenzvariable verwenden, um den Timer zu speichern und dann zu löschen. Nachfolgend finden Sie ein Beispiel für die Implementierung von Debouncing in React ohne die Verwendung eines Drittanbieterpakets

import { useState, useRef } from "react";
import "./styles.css";

export default function App() {
  // Variablen für Debouncing
  const [text, setText] = useState("");
  const timer = useRef();

  // Variablen für Throtteling
  const [throttle, setThrottle] = useState(false)

  const handleDebouncing = ({ target }) => {
    clearTimeout(timer.current)

    timer.current = setTimeout(() => {
      callApi();
    }, 300);

    setText(target.value);
  };

  const handleThrottleing = () => {
    callApi()

    setThrottle(true)

    setTimeout(() => {
      setThrottle(false)
    }, 2000)
  }

  const callApi = () => {
    console.log("API aufrufen");
  };

  return (

      Klicken Sie hier, um das Throtteling zu sehen

  );
}

0voto

Coding Elements Punkte 940

Sie müssen useCallback verwenden, wie im Blogbeitrag How to use debounce and throttle in React and abstract them into hooks erwähnt.

import React, { useCallback } from 'react';
import debounce from 'debounce'; // Oder ein anderes Paket

function App() {
    ...
    const debouncedSave = useCallback(
        debounce(x => foo(x), 1000),
        [], // Wird nur einmal initial erstellt
    );
    ...
}

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