Hogyan kell használni a Debounce és a Throttle-t a React-ban, és elvonni őket horgokba

A horgok ragyogó kiegészítői a React-nek. Nagyon sok logikát egyszerűsítenek, amelyeket korábban különböző életciklusokra kellett felosztani classalkatrészekkel.

Mindazonáltal más mentális modellt igényelnek , különösen az elsősök számára.

Ezen a cikken egy rövid videósort is rögzítettem, amely hasznos lehet.

Visszavonás és fojtás

Rengeteg blogbejegyzés van írva a visszavonásról és a fojtószelepről, így nem fogok belemerülni a saját visszavonás és gázadás írásába. A rövidség kedvéért vegye figyelembe debounceés vegye figyelembe throttleLodash-t.

Ha gyors frissítésre van szüksége, fogadjon el egy (visszahívási) funkciót és egy milliszekundumos késleltetést (mondjuk x), majd mindkettő egy másik funkciót ad vissza különleges viselkedéssel:

  • debounce: Visszaadja a funkció, hogy lehet nevezni tetszőleges számú alkalommal (lehetőleg gyors egymásutánban), de csak akkor Elindítja a visszahívás várakozás után az xms az utolsó hívást.
  • throttle: Visszaadja a funkció, hogy lehet nevezni tetszőleges számú alkalommal (lehetőleg gyors egymásutánban), de csak akkor Invoke a visszahívás legfeljebb egyszer minden xms.

Usecase

Van egy minimális blogszerkesztőnk (itt a GitHub repo), és szeretnénk a blogbejegyzést 1 másodperccel az adatbázisba menteni, miután a felhasználó abbahagyja a gépelést.

Hivatkozhat erre a Codesandboxra is, ha szeretné megtekinteni a kód végleges változatát.

Szerkesztőnk minimális verziója így néz ki:

import React, { useState } from 'react'; import debounce from 'lodash.debounce'; function App() { const [value, setValue] = useState(''); const [dbValue, saveToDb] = useState(''); // would be an API call normally const handleChange = event => { setValue(event.target.value); }; return (  

Blog

Editor (Client)

{value}

Saved (DB)

{dbValue} ); }

Itt saveToDbvalójában API-hívás lenne a háttérprogram. A dolgok egyszerűsége érdekében állapotban mentem, majd másként renderelem dbValue.

Mivel mi csak azt akarjuk, hogy végre ezt a műveletet még egyszer megtakarítás felhasználó befejezte a gépelést (1 másodperc után), ezt kell debounced .

Itt van az indító kód repo és elágazás.

Lemondott függvény létrehozása

Először is szükségünk van egy visszavezetett függvényre, amely befogadja a hívást saveToDb:

import React, { useState } from 'react'; import debounce from 'lodash.debounce'; function App() { const [value, setValue] = useState(''); const [dbValue, saveToDb] = useState(''); // would be an API call normally const handleChange = event => { const { value: nextValue } = event.target; setValue(nextValue); // highlight-starts const debouncedSave = debounce(() => saveToDb(nextValue), 1000); debouncedSave(); // highlight-ends }; return {/* Same as before */}; } 

De ez valójában nem működik, mert a függvény debouncedSaveminden handleChangehíváskor frissen jön létre . Ennek eredményeként minden billentyűleütés visszavonásra kerül, nem pedig a teljes bemeneti érték.

useCallback

useCallbackáltalában a teljesítmény optimalizálására használják, amikor a visszahívásokat átirányítják a gyermek alkotórészeinek. De használhatjuk a visszahívási függvény memoarizálásának korlátozását annak biztosítására, hogy a debouncedSavereferenciák ugyanazon visszavonott függvényt jelenítsék meg a megjelenítések során .

Ezt a cikket itt írtam a freeCodeCamp-on is, ha meg szeretné érteni az emlékeztetés alapjait.

Ez a várakozásoknak megfelelően működik:

import React, { useState, useCallback } from 'react'; import debounce from 'lodash.debounce'; function App() { const [value, setValue] = useState(''); const [dbValue, saveToDb] = useState(''); // would be an API call normally // highlight-starts const debouncedSave = useCallback( debounce(nextValue => saveToDb(nextValue), 1000), [], // will be created only once initially ); // highlight-ends const handleChange = event => { const { value: nextValue } = event.target; setValue(nextValue); // Even though handleChange is created on each render and executed // it references the same debouncedSave that was created initially debouncedSave(nextValue); }; return {/* Same as before */}; } 

useRef

useRefad egy mutatható objektumot, amelynek currenttulajdonsága az átadott kezdeti értékre utal. Ha nem változtatjuk meg manuálisan, akkor az érték a komponens teljes élettartama alatt megmarad.

Ez hasonlít az osztálypéldányok tulajdonságaihoz (azaz a metódusok és tulajdonságok meghatározásához this).

Ez szintén a várakozásoknak megfelelően működik:

import React, { useState, useRef } from 'react'; import debounce from 'lodash.debounce'; function App() { const [value, setValue] = useState(''); const [dbValue, saveToDb] = useState(''); // would be an API call normally // This remains same across renders // highlight-starts const debouncedSave = useRef(debounce(nextValue => saveToDb(nextValue), 1000)) .current; // highlight-ends const handleChange = event => { const { value: nextValue } = event.target; setValue(nextValue); // Even though handleChange is created on each render and executed // it references the same debouncedSave that was created initially debouncedSave(nextValue); }; return {/* Same as before */}; } 

Olvassa tovább a blogomon, hogy miként lehet elvontatni ezeket a fogalmakat egyedi horgokba, vagy nézze meg a videósorozatot.

Kövess engem a Twitteren is, hogy naprakész legyek a legfrissebb bejegyzéseimről. Remélem, hasznosnak találta ezt a bejegyzést. :)