To create a buffeting or throttling function using a buffeting/throttling function in a class component, usually by wrapping the function that requires buffeting/throttling with debounce/ Throttle:

import React from 'react'; import ReactDOM from 'react-dom'; import 'antd/dist/antd.css'; import { Input } from 'antd'; import throttle from 'lodash/debounce'; class Search extends React.Component { constructor(props) { super(props) this.handleSearch = throttle(this.handleOnChange, 200); } handleOnChange = (e) => { console.log(e.target.value) } render() { return ( <Input onChange={this.handleSearch} /> ) }  } ReactDOM.render( <Search />, document.getElementById('container'), );Copy the code

When we use anti-shock/throttling functions in functional components, it is also natural to use debounce/ throttle to wrap functions that require anti-shock/throttling:

import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import { Input } from 'antd';
// import debounce from 'lodash/debounce';
import throttle from 'lodash/throttle';

const Search = () => {

  const handleOnChange = (e) => {
    console.log(e.target.value)
  }
  const handleSearch = throttle((e) => handleOnChange(e), 500)



  return (<Input onChange={handleSearch}  placeholder="Basic usage" />)
}

ReactDOM.render(<Search />, document.getElementById('container'));
Copy the code

It turns out that the function that does the throttling doesn’t work, but only delays the time by 500 milliseconds. This is because the internal variables of a functional component are released after each rendering, and all variables are reinitialized upon re-rendering, resulting in the setTimeout function being registered and executed each time. To get proper results, you must somehow store references to variables and methods that will be deleted, and unfortunately you can’t use the useState hook to do that directly. So how do we store it? Thankfully, two hooks, useCallback and useRef, solved our problem.

useCallback

When an array of callback dependencies is passed to useCallback as an argument, it returns a cached function.

import React, { useCallback } from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import { Input } from 'antd';
import debounce from 'lodash/debounce';
import throttle from 'lodash/throttle';

const Search = () => {

  const handleOnChange = (e) => {
    console.log(e.target.value)
  }
  const handleSearch = useCallback(throttle((e) => handleOnChange(e), 500), [])

  return (<Input onChange={handleSearch}  placeholder="Basic usage" />)
}

ReactDOM.render(<Search />, document.getElementById('container'));
Copy the code

useRef

UseRef returns a mutable ref object whose.current property is initialized as the passed parameter (initialValue). The returned REF object catalpa component remains unchanged throughout its life.

import React, { useRef } from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import { Input } from 'antd';
import debounce from 'lodash/debounce';
import throttle from 'lodash/throttle';

const Search = () => {

  const handleOnChange = (e) => {
    console.log(e.target.value)
  }
  const handleSearch = useRef(throttle((e) => handleOnChange(e), 500)).current

  return (<Input onChange={handleSearch}  placeholder="Basic usage" />)
}

ReactDOM.render(<Search />, document.getElementById('container'));
Copy the code