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