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

19voto

superluminary Punkte 42702

2022 - Verwenden Sie ein useEffect-Hook

Ihre beste Option zu diesem Zeitpunkt ist die Verwendung des useEffect-Hooks. useEffect ermöglicht es Ihnen, eine Funktion festzulegen, die den Zustand in Reaktion auf ein asynchrones Ereignis ändern kann. Debouncing ist asynchron, daher eignet sich useEffect gut für diesen Zweck.

Wenn Sie eine Funktion aus dem Hook zurückgeben, wird die zurückgegebene Funktion aufgerufen, bevor der Hook erneut aufgerufen wird. Dadurch können Sie den vorherigen Timeout abbrechen und die Funktion effektiv debouncen.

Beispiel

Hier haben wir zwei Zustände, value und tempValue. Das Setzen von tempValue löst einen useEffect-Hook aus, der einen Timeout von 1000 ms startet, der eine Funktion aufruft, um tempValue in value zu kopieren.

Der Hook gibt eine Funktion zurück, die den Timer aufhebt. Wenn der Hook erneut aufgerufen wird (d. h., eine weitere Taste gedrückt wird), wird der Timeout abgebrochen und zurückgesetzt.

const DebounceDemo = () => {
  const [value, setValue] = useState();
  const [tempValue, setTempValue] = useState();

  // Dieser Hook wird einen 1000-ms-Zeitgeber setzen, um tempValue in value zu kopieren
  // Wenn der Hook erneut aufgerufen wird, wird der Timer abgebrochen
  // Dies erzeugt ein Debouncing
  useEffect(
    () => {
      // Warten Sie 1000 ms, bevor Sie den Wert von tempValue in value kopieren;
      const timeout = setTimeout(() => {
        setValue(tempValue);
      }, 1000);

      // Wenn der Hook erneut aufgerufen wird, brechen Sie den vorherigen Timeout ab
      // Dadurch wird ein Debouncing anstelle einer Verzögerung erzeugt
      return () => clearTimeout(timeout);
    },
    // Führen Sie den Hook jedes Mal aus, wenn der Benutzer eine Taste drückt
    [tempValue]
  )

  // Hier erstellen wir eine Eingabe, um tempValue zu setzen.
  // value wird 1000 ms nach dem letzten Aufruf des Hooks aktualisiert,
  // d. h. nach der letzten Tastatureingabe des Benutzers.
  return (
    <>
       setTempValue(target.value)
        }
      />
      { value }

  )
}

18voto

sledgeweight Punkte 6823

Ich habe diesen Beitrag von Justin Tulk sehr hilfreich gefunden. Nach ein paar Versuchen, auf die offiziellere Weise mit React/Redux, zeigt es sich, dass es aufgrund von React's synthetischem Event-Pooling scheitert. Seine Lösung verwendet dann einige interne Zustände, um den geänderten/eingegebenen Wert im Eingabefeld zu verfolgen, mit einem Callback gleich nach setState, der eine zeitverzögerte/reduzierte Redux-Aktion aufruft, um einige Echtzeit-Ergebnisse zu zeigen.

import React, {Component} from 'react'
import TextField from 'material-ui/TextField'
import { debounce } from 'lodash'

class TableSearch extends Component {

  constructor(props){
    super(props)

    this.state = {
        value: props.value
    }

    this.changeSearch = debounce(this.props.changeSearch, 250)
  }

  handleChange = (e) => {
    const val = e.target.value

    this.setState({ value: val }, () => {
      this.changeSearch(val)
    })
  }

  render() {

    return (

    )
  }
}

17voto

Mohan Dere Punkte 4067

Mit debounce müssen Sie das ursprüngliche synthetische Ereignis mit event.persist() behalten. Hier ist ein funktionierendes Beispiel, das mit React 16+ getestet wurde.

import React, { Component } from 'react';
import debounce from 'lodash/debounce'

class ItemType extends Component {

  evntHandler = debounce((e) => {
    console.log(e)
  }, 500);

  render() {
    return (
       {
        e.persist()
        this.evntHandler(e)
      }}>
        ...

    );
  }
}
export default ItemType;

Mit einer Funktionskomponente können Sie Folgendes tun -

const Search = ({ getBooks, query }) => {

  const handleOnSubmit = (e) => {
    e.preventDefault();
  }
  const debouncedGetBooks = debounce(query => {
    getBooks(query);
  }, 700);

  const onInputChange = e => {
    debouncedGetBooks(e.target.value)
  }

  return (

            Suchen Sie im umfassendsten Index der Welt nach Volltextbüchern.

          Suche

  )
}

Verweise - - https://gist.github.com/elijahmanor/08fc6c8468c994c844213e4a4344a709 - https://blog.revathskumar.com/2016/02/reactjs-using-debounce-in-react-components.html

15voto

Yura Punkte 2681

Wenn Sie nur das DOM-Eingabeelement aus dem Event-Objekt benötigen, ist die Lösung viel einfacher - verwenden Sie einfach ref. Beachten Sie, dass dies Underscore erfordert:

class Item extends React.Component {
    constructor(props) {
        super(props);
        this.saveTitle = _.throttle(this.saveTitle.bind(this), 1000);
    }
    saveTitle(){
        let val = this.inputTitle.value;
        // ajax Anfrage durchführen
    }
    render() {
        return  this.inputTitle = el } 
                    type="text" 
                    defaultValue={this.props.title} 
                    onChange={this.saveTitle} />
    }
}

12voto

Art Punkte 22351

Es gibt ein use-debounce Paket, das Sie mit ReactJS Hooks verwenden können.

Aus der README des Pakets:

import { useDebounce } from 'use-debounce';

export default function Input() {
  const [text, setText] = useState('Hallo');
  const [value] = useDebounce(text, 1000);

  return (

       {
          setText(e.target.value);
        }}
      />
      Aktueller Wert: {text}
      Debounce Wert: {value}

  );
}

Wie Sie aus dem obigen Beispiel sehen können, ist es so eingerichtet, dass die Variable value nur einmal pro Sekunde (1000 Millisekunden) aktualisiert wird.

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