Kuinka käyttää Debounce ja Throttle React -ohjelmassa ja tiivistää ne koukkuihin

Koukut ovat loistava lisäys Reactille. Ne yksinkertaistavat paljon logiikkaa, joka aiemmin oli jaettava eri elinkaareihin classkomponenttien kanssa.

He vaativat kuitenkin erilaista henkistä mallia, etenkin ensikertalaisille.

Nauhoitin tähän artikkeliin myös lyhyen videosarjan, josta saatat löytää apua.

Pysäytä ja kaasu

On olemassa joukko blogiviestejä, jotka on kirjoitettu poistumisesta ja kaasusta, joten en aio sukeltaa siihen, kuinka kirjoittaa oma debounce ja kaasu. Lyhyyyden vuoksi harkitse debounceja throttleLodashia.

Jos tarvitset nopean päivityksen, hyväksy molemmat (takaisinsoitto) -toiminto ja viive millisekunneissa (sano x) ja palauta sitten molemmat toisen toiminnon erityisellä käyttäytymisellä:

  • debounce: Palauttaa toiminto, jota voidaan kutsua niin monta kertaa (mahdollisesti nopea perintöasioihin), mutta vain vedota soittopyyntö odotettuaan varten xms viimeisen puhelun.
  • throttle: Palauttaa toiminto, jota voidaan kutsua niin monta kertaa (mahdollisesti nopeasti peräkkäin), mutta vain vedota soittopyyntö korkeintaan kerran jokaisessa xms.

Käytä

Meillä on vähäinen blogieditori (tässä on GitHub-repo), ja haluaisimme tallentaa blogiviestin tietokantaan 1 sekunnin kuluttua siitä, kun käyttäjä lopettaa kirjoittamisen.

Voit viitata myös tähän koodihiekkalaatikkoon, jos haluat nähdä koodin lopullisen version.

Pienin versio editoristamme näyttää tältä:

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

Tässä saveToDbolisi oikeastaan ​​API-kutsu backendille. Pitääksesi asiat yksinkertaisina, tallennan sen tilaan ja hahmonnaan sitten nimellä dbValue.

Koska me vain haluamme tehdä tämän tallennusta, kun käyttäjä on lopettanut kirjoittamisen (1 sekunnin jälkeen), tämä tulisi debounced .

Tässä on aloituskoodin repo ja haara.

Poistetun toiminnon luominen

Ensinnäkin tarvitsemme poistetun toiminnon, joka kutsuu puhelun 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 */}; } 

Mutta tämä ei todellakaan toimi, koska toiminto debouncedSaveluodaan uudestaan ​​jokaiselle handleChangepuhelulle. Tämä lopulta purkaa jokaisen näppäimen painalluksen pikemminkin kuin koko syötetyn arvon.

useCallback

useCallbackkäytetään yleisesti suorituskyvyn optimointiin, kun soitot soitetaan takaisin alikomponenteille. Mutta voimme käyttää sen rajoitusta, joka koskee soittopyynnön muistiinpanoa, jotta varmistetaan, että debouncedSaveviittaukset ovat sama poistettu toiminto hahmonnuksissa .

Kirjoitin myös tämän artikkelin täällä freeCodeCampissa, jos haluat ymmärtää muistiinpanon perusteet.

Tämä toimii odotetusti:

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

useRefantaa muutettavan objektin, jonka currentominaisuus viittaa välitettyyn alkuarvoon. Jos emme muuta sitä manuaalisesti, arvo säilyy komponentin koko käyttöiän ajan.

Tämä on samanlainen kuin luokan esiintymäominaisuudet (eli menetelmien ja ominaisuuksien määrittely this).

Tämä toimii myös odotetusti:

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

Jatka lukemista blogissani, kuinka abstraktit nämä käsitteet mukautettuihin koukkuihin tai tutustu videosarjaan.

Voit myös seurata minua Twitterissä pysyäksesi ajan tasalla uusimmista viesteistäni. Toivon, että pidit tästä viestistä hyödyllistä. :)