The application of anti-shake in React functional components (React + Hook + Typescript).

Original link: https://www.insidentally.com/articles/000030/

Anti-shake means that the function will only be executed once within n seconds after the high-frequency event is triggered. If the high-frequency event is triggered again within n seconds, the time will be recalculated.

If the response frequency of some event response functions is unrestricted, it will not only increase the burden on the browser, but also easily cause the page to freeze and affect the user’s experience. Therefore, the use of anti-shake can limit the calling frequency of the event processing function and improve the user’s experience without affecting the actual effect.

Simple anti-shake function

Take advantage of the Javascript closure feature to save a timer Timeout and update it in its sub-functions.

 1
2
3
4
5
6
7
8
9
10
11
12
 function debounce ( fn, wait ) {
var timeout
return function ( ) {
var context = this ,
args = arguments
clearTimeout (timeout)

timeout = setTimeout ( function ( ) {
fn.apply (context, args)
}, wait)
}
}

The operation of the function is as follows:

  1. Create a timer after the function is triggered
  2. Update the reset timer if the function is triggered again before the timer expires
  3. Trigger the function fn when the timer ends

Debounce functions in React functional components

The above debounce function cannot take effect in React. The reason is that every time the functional component is rendered, the function will be rebuilt, which will cause the timer in the debounce function to be recreated, which will cause the debounce to fail. At present, there are two commonly used methods on the Internet:

  1. Use useRef to cache timers

     1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     function useDebounce ( fn,delay ){
    //fn is the function that needs anti-shake
    const refTimer = useRef ();

    return function f ( ...args ){
    if (refTimer. current ){
    clearTimeout ( refTimer.current );
    }
    refTimmer.current = setTimeout ( () => {
    fn (args);
    }, delay)
    }
    }
  2. Cache function with useCallback

     1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     function Debounce ( ){
    const click = useCallback ( clickInner (),[]);

    function clickInner ( ){
    let timer;
    return function ( e ){
    if (timer){
    clearTimeout (timer);
    }
    timer = setTimeout ( () => {
    //todo
    //Related operations of event e
    }, 1000 )
    }
    }
    }

The above two methods are the application of the anti-shake function in the React component function.

Anti-shake function in React + Hook + Typescript

A static type definition has been added to Typescript, and the above function can be slightly modified:

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
twenty one
twenty two
twenty three
twenty four
 import { useCallback, useEffect, useRef } from "react" ;

interface ICurrent {
fun : Function ,
timer : null | NodeJS . Timeout
}

function useDebounce ( fn: (args: any ) => void , delay: number , dep: any = [] ) {
const { current } = useRef< ICurrent >({ fun : fn, timer : null });
useEffect ( function ( ) {
current. fun = fn;
}, [fn]);

return useCallback ( ( args: any ) => {
if (current. timer ) {
clearTimeout (current. timer );
}
current.timer = setTimeout ( () => {
current. fun (args);
}, delay)
}, dep)
}

export default useDebounce;

The calling method is as follows (take the Slider component in Ant Design as an example):

 1
2
3
4
5
6
7
8
9
10
11
12
 const onChangeR = useDebounce ( ( newValue: number ) => {
fireColor.R = newValue;
setColorState (fireColor);
setInputValueR (newValue);
changeColor ();
}, 500 );
return ( < Slider
min = {0}
max = {255}
onChange = {onChangeR}
value = {typeof inputValueR === 'number' ? inputValueR : 0 }
/> )

In fact, the anti-shake function written by myself does not perform well on the Slider component of Ant Design. The Slider component itself provides two different APIs, onChange and onAfterChange. The trigger timing of onAfterChange and onMouseUp is the same, and the incoming value is Slider The current value of onAfterChange can be used as onChange after anti-shake.

When writing and using a custom useDebounce, I encountered some other difficulties related to the features of React Hook, which I will introduce and analyze in the following React study notes.

This article is reprinted from: https://www.insidentally.com/articles/000030/
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment