preface

Both props and State are JS objects used by components to store data. The former is the external exposed data interface, and the latter is the internal component state. They determine the appearance of the UI interface, and you want the user to interact with the interface

That is, the Web browser notifies the application of something that has happened, such as a mouse click, a movement, a keyboard press, etc. The page responds accordingly. It is a specific moment of interaction between the user and a document or browser window. This is where events come in

In native JS manipulation of the DOM, there is often an inline mode

  • Direct event binding in HTML
     <p onclick="Alert (' Follow wechat itclanCoder ')"></p>
Copy the code
  • Direct binding
Object. Event type = anonymous function,obj.onclick =function` () {})Copy the code

DOM objects for event listening processing, event delegate listening mode

(object addEventListener (.'Event type, without on', callback function))Copy the code

React handles events similarly but differently. How do you ensure that functions can access component properties?

How do I pass parameters to the event handler callback?

How do I prevent functions from being called too quickly or too many times? What’s the solution?

Frequent DOM manipulation can cause the browser to lag and not respond in a timely manner, causing the browser to redraw and rearrange, which increases the stress on the browser

Frequently call background interface, good interface is you play bad, resulting in page blank, crash, easy to be back-end students to see the knife

Both improve user experience and reduce overhead on the server side

So here’s what you want to know

React handles events for a better reading experience with more potable links

Events in React

React event bindings are written directly to JSX elements and do not need to be monitored by addEventListener event delegates.

  • Add events to JSX elements inline with on*EventType, name them in camelCase, not lowercase, without calling addEventListener to listen for events. Also need not consider compatibility, the React has wrapped up some event type attribute (ps: onClick, onMouseMove and onChange, an onFocus), etc
  • When using JSX syntax, you need to pass in a function as an event handler, not a string; that is, the props value should be function type data, and the event function method should be wrapped in double curly braces
  • The on*EventType attribute can only be used on normal native HTML tagsDiv,input,a,p, etc.<div onClick={event handler}></div>),Cannot be used directly on custom component labels.Which is: this is not going to work
  • It cannot prevent the default behavior by returning false, it must show preventDefault as shown below
function handleClick(event){
  event.preventDefault();    
}
Copy the code

The event object

An event is a web browser that notifies the application of what has happened, such as a mouse click, a move, a keyboard press, etc.

It is not a javascript object, but the event handler that is triggered by the event receives the event object argument, which records some detailed information about the event

 <a href="#"OnClick = {this.handlelink} > link </a> handleLink(event){event.preventdefault (); console.log(event); }Copy the code

Event records information about the event object, as shown in the following figure

React encapsulates the event object of the native browser and provides a common API without considering the compatibility of various browsers

Same as if the native browser handles event bubulation (Event.stoppropatation) and prevents the default (event.preventDefault) from being used

This binding performance comparison

We learned about the this binding in the previous section, but we’ll take it out again to illustrate its importance

When you bind event listener handlers to JSX elements, you bind the event handler to the instance of the current component for this: to get props from the parent component

There are several ways to ensure that functions can access component properties

  • Bind in constructor to bind this environment in constructor, initializing the event listener handler
class Button extends Component{ constructor(props){ super(props); HandleBtnClick = this.handlebtnclick.bind (this); }render() {return<div> <button onClick={this.handlebtnclick}> </button> </div>); }handleBtnClick(){ alert(this); }}Copy the code

When doing event listening binding on JSX, for this in the JSX callback, Since the class method in Es6 does not bind this by default, if you do not bind this, forget to bind the event handler, and pass it to the event method (onClick above), the value of this will be undefined

To solve this problem: One option is to bind this environment in the constructor function as described above. This method is recommended by React and has better performance

The second way is to bind this directly on JSX, using bind in Reander

<button onClick={this.handlebtnclick.bind (this)}>Copy the code

Use this bind directly binding, each rendering component, will create a new function, in general, this kind of writing is no problem, but if the callback function as a prop value into child components, these components will be additional to apply colours to a drawing, can affect performance, this and use the arrow function also have this problem

Solutions:

  • Bind in the constructor function, as shown above:
  • Use the class fields syntax
Class Button extends Component{// handleClick = () => {alert()Learn the Basics of React);
    }
    render() {return<div> <button onClick={this.handlebtnclick}> </button> </div>); }}Copy the code

If you don’t use the class field syntax, you can use the arrow function in the callback, which is equivalent

class Button extends Component{
   
   
    handleClick()
        alert(Learn the Basics of React);
    }
    render() {return(<div> <button onClick={() => {this.handlebtnclick}}> button </button> </div>); }}Copy the code

This approach has the same performance issues as using bind to bind this environment directly in the Render function, which is bound to Render when the event handler is passed as a prop to the child component

So for performance reasons, put the this binding in constructr or use class field syntax to solve the performance bottleneck

Pass parameters to the event handler

In the loop operation list, sometimes we need to pass some extra parameters to the event handler to perform some operations, such as index, which row ID to delete. You can pass parameters to the event handler either way

< button onClick = {this. HandleBtnDelete. Bind (this, id)} > delete < / butto/n > or < button onClick = {(e) = > enclosing handleDelete (id, E)}> delete </button>Copy the code

Here is an example of deleting a list, as shown in the code

import React, { Fragment, Component } from 'react';      
import ReactDOM from 'react-dom';

class List extends Component {
  constructor(props){
    super(props);

    const { list } = this.props;
    this.state = {
      list: list
    }
    
  }

  render(){
    const { list } = this.state;
    return( <Fragment> <ul> { // list.map((item, index) => <li onClick={ this.handleDelete.bind(this, index)} key={index}>{ item }</li>) list.map((item, index) => <li onClick={ (e) => this.handleDelete(index, e)} key={index}>{ item }</li>) } </ul> </Fragment> ); } handleDelete(index, E){console.log(e) // copy a copy of state, do not change state directly, React does not allow any changes to state const list = [...this.state.list]; list.splice(index,1); this.setState(() => ({ list: list })) } } const listData = ["itclanCoder"."Chuan chuan"."chrome"."Firefox"."IE"]


const container = document.getElementById('root');

ReactDOM.render(<List list={ listData }  />, container);
Copy the code

In the above code, binding (function.proptype. bind) in the render Function and wrapping the event handler with the arrow Function to pass arguments to the event listener handler are equivalent, respectively

<button onClick = { this.handleBtnClick(this, </button onClick = {() => this.handlebtnclick (id)}></button>Copy the code

To use the arrow function, the React event object is passed as a second argument and must be passed explicitly

By using bind, the event object and more parameters will be passed in implicitly

Binding directly through the bind method in the Render function creates a new function each time the component renders, which affects performance: it is better to bind this environment in the constructor function, since the constructor function only executes once

constructor(props){ super(props); HandleDelete = this.handleDelete.bind(this); }Copy the code

Fixed the issue of event handlers being rendered repeatedly every time

In Es5, when a function is called, the name of the function is usually enclosed in parentheses. In JSX, when the React element is bound to an event handler, it is customary to do so by accident

This will cause this function to be called every time the component renders, causing unnecessary render functions that will cause performance problems

You should make sure that when you pass a function to a component, it is not called immediately, as shown below

render() {return (
       <button onClick = { this.handleClick()}>button</button>
    );
}
Copy the code

Instead, you should pass the event function itself (without parentheses) as shown below

render(){
   <button onClick = { this.handleClick }>button</button> 
}
Copy the code

Here is the focus of this section. I have heard of functions such as throttling and anti-shaking, but I do not necessarily understand them

How to prevent functions from being called too quickly (function throttling) or too many times (function stabilization)

Sometimes, when users frequently interact with UI interface operations, such as window adjustment (triggering resize), page scrolling, scroll loading (triggering scroll), form button submission, shopping mall crazy click (triggering mousedown), and real-time search (keyup,input), drag and drop, etc

When you frequently trigger the user interface, you will constantly trigger event handlers. In other words, when there is continuous clicking, pull-up loading, real-time search, frequent manipulation of DOM elements, request for resource loading and other performance consuming operations, the interface may freeze, the browser will crash, the page will be blank and so on

The solution to this problem is function throttling and function stabilization

Function throttling definition: saving (reducing) the frequency of triggering event handlers, continuously triggering function execution at certain intervals, it is a means of optimizing the high frequency execution of a section of JS code

Features: No matter how frequently an event is triggered, the event handler is guaranteed to actually execute at a specified interval

Application scenario: It is usually used to click the mouse repeatedly, move the mouse mousemove, drag and drop, resize the window, onScroll scroll, refresh lazy loading

Principle: The function is triggered by judging whether a certain time has been reached. If there is no specified time, the timer is used to delay, and the next event will reset the timer. It is executed at an interval

Common operations with the user interface are:

  • Mouse wheel page onScroll, scroll down to refresh lazy loading
  • Window size change (onresize)
  • Drag and drop

If high frequency operation, if not for a certain processing, will inevitably cause data request for many times, the pressure of the server, so that the performance of the code is very inefficient, impact performance, reduce the frequent operation of an important means, is to reduce the frequency, through the throttle control, also is to make the core function code in a certain time, how often do a

Throttling ensures that core code is executed only once in a period of time

You can think of an example of saving water in your life (the Three Gorges Dam has many sluice gates) :

High-frequency events are like a wide open faucet, with a large amount of water flowing out continuously, just like the continuous execution of the code. If not controlled, it will cause a waste of resources

In the corresponding page, if the submit button is continuously clicked in the form, the scrolling events are monitored, and the resources of the server are continuously pulled down and loaded

To throttle, tighten the faucet to reduce the frequency of its water flow, drop a drop of water every once in a while, so as to save resources

In the code is reflected: set up a timer, let the core function of the code, compartments to execute

Below is a mouse wheel, throttling operation to achieve: similar to continuous operation, are so, continuously click the button, pull up to load throttling mode one: timestamp + timer

/* Throttle1 function, throttle1: timestamp + timer * @params method,duration The first argument is the actual function to execute when the event is triggered * the second argument is the defined interval * * Principle: by judging whether to reach a certain amount of time to trigger function, if not use the timer to delay time, while the next event will reset the timer, it is a time interval to perform, no matter how frequently, event triggers will guarantee within the specified event is bound to perform a real event handler * * * /functionthrottle1(method, duration) { var timer = null; var prevTime = new Date(); // The previous timereturn function() {var that = this, currentTime = new Date(), resTime = currentTime-prevTime; // Time stamp // Prints the time difference between the current world and the last world console.log("Time difference", resTime); // The time since the last execution is shorter than the set intervalif(resTime < duration) {// Clear the last timer, cancel the last queue task, and reset the timer. This ensures that the function is fired only once within 500 ms seconds, achieving the purpose of function throttling clearTimeout(timer); timer =setTimeout(function(){
    	 				prevTime = currentTime;
    	 				method.apply(that);
    	 			}, duration)
    	 		}elsePrevTime = currentTime; prevTime = currentTime; prevTime = currentTime; method.apply(that); }}} // Event-triggered methods (functions), function throttling 1function handleJieLiu1(){
    	 	console.log("Throttling Mode 1");
    	 }   
    	 
    	  var handleJieLiu1 = throttle1(handleJieLiu1, 500);
    	  document.addEventListener('mousewheel', handleJieLiu1);
Copy the code

Throttling mode 2:

/* * throttle2 function throttle2 implementation mode 2: reset a switch variable + timer * @params method,duration parameter is consistent with the above meaning * @returnThrottle2 returns an event handler * * that defines the initial value of runFlag when throttle2 is executed, returns an anonymous function via a closure as an event handler, * * Determine the status of runFlag within the returned function and determine whether to execute the real function method or to jump out. Each execution of method changes the status of runFlag, and a timer is used to reset the status of runFlag locks within the specified durtion interval * */functionThrottle2 (method, duration){// Whether methods are executed within the current interval, set a switch to identify var runFlag =false; // Return an event handlerreturn function(e) {// Check whether there is a method to execute, if there is, do nothing, iftrue, then jump outif(runFlag){
         			return false; } // Start running runFlag =true; // Add a timer to reset the lock state when the interval is reachedsetTimeout(function(){ method(e); // When the execution is complete, declare that no method is currently executing, so that the next time to call runFlag =false; }, duration)}} // Event-triggered methods (functions), function throttling 2function handleJieLiu2(){
    		console.log("Throttling Mode 2");
    	}
    	var handleJieLiu2 = throttle2(handleJieLiu2, 500);
    	document.addEventListener('mousewheel', handleJieLiu2);
Copy the code

The above two ways to implement function throttling can be achieved to prevent users from frequent operations caused by repeated requests for resources

The specific effect is as follows:

From the effect example above, the event handlers are executed in a different order when the mouse wheel is constantly scrolling

It is recommended to use the first function throttling method when given a wide range of time, such as 1 hour, every few minutes and no more than 1 hour

It is recommended to use the second function throttling method if the execution is required only once in a certain period of time

Function image stabilization

Definition: Prevent jitter, repeated trigger, frequent operation, the core is to delay the execution of the event handler function, perform only the last operation within a certain period of time, for example: the form submitted several times, the recommended use of shake prevention

In other words, the event handler is not executed when successive events are fired, but only when the last successive event is fired in a certain phase, following two conditions

  • You have to wait a while
  • The last trigger interval must be greater than the set value before execution

In life, you can imagine a bus driver waiting for someone to get on the bus before getting out of the station

Application scenario: It is usually applied to the input box events keyDown, keyUp, and associative query. Ajax requests are sent only when the user stops keyboard input

How it works: It maintains a timer that specifies that an event handler is triggered after the duration, but any time the event handler is triggered again within the duration, the current timer is cleared and the timer is retimed, so that only the last event handler is actually fired

The specific code is as follows:

/* * function to prevent tremors * example: Assume that the time interval is 500ms, the frequent different operations are 5s, and the execution time of each two times is less than or equal to the interval of 500ms *, then only one execution is performed in the end, * @params method,duration, same as above How it works: It maintains a timer that sets the timer handler to start after duration, but any timer that starts again within duration clears the current timer so that only the last operation is actually triggered * * Generally used for input box events, the common scenario is the form of search or associative query, if you do not use the anti-shake will continue to send requests, increase the pressure on the server, after the use of anti-shake, will be in the user input keywords to query before sending requests, Baidu search is so realizedfunction debounce(method, duration) {
         	var timer = null;
         	return function(){ var that = this, args = arguments; // If a method is executing during an interval between calls, the execution of the method is terminatedif(timer) { clearTimeout(timer); } // start the call timer =setTimeout(function(){ method.apply(that,args); }, duration)}} // Event trigger method (function), anti-shakefunction handleFangDou(){
    		console.log("Function stabilization",new Date());
    	}
    	var handleFangDou = debounce(handleFangDou, 500);
    	var oInput = document.querySelector("#input"); // Get the input element oinput. addEventListener('keyup',handleFangDou);

Copy the code

The specific effect is as follows:

Similarly, the search engine, the form’s associative query function, does not make Ajax data requests based on the letter, number, and content that the user types. If every letter you type triggers a data request, it will cost performance

Should be when the user stops typing to trigger the query request, this time to use the function tremble

Form multiple submission, Baidu search and so on are used to achieve a summary:

Thing in common: Is to solve the frequent operation trigger event handler, caused the page caton, not smooth performance problems, such as are logical to enhance performance by setting the delay timer, to reduce the number of HTTP requests, save request resources difference: function throttling, within the time interval between the event handler, stabilization and function, and only perform the last operation within a certain time interval

In React, how to implement function throttling and function anti-shock?

React borrows a loadsh.throttle library to implement throttling functions

First you need to install the library from the command line terminal via NPM or CNPM

cnpm i -S lodash.throttle
Copy the code

You’ll then introduce you into the React component and call throttle, which takes in two parameters: the event handler to fire and the number of seconds it should be invoked

Below is the throttling code for the function, which cannot be called more than once in a given time, to the click event handler so that it can only be called once per second

import React, { Fragment, Component } from 'react';      
import ReactDOM from 'react-dom';
import throttle from 'lodash.throttle'; Class LoadMoreButton extends Component {constructor(props) {super(props); this.state = { tip:' ', trigerTimes: 1 } this.handleClick = this.handleClick.bind(this); this.handleClickThrottled = throttle(this.handleClick, 1000); // Pass the trigger event handler as the first argument, and the second argument is the time of the interval, in this case 1 second}componentWillUnmount() {
    this.handleClickThrottled.cancel();
  }

  render() {
    return(
      <Fragment>
          <div><button onClick={ this.handleClickThrottled }>Load More</button></div>
          <div>{ this.state.tip }</div>
      </Fragment>
        
    ) 
  }

  handleClick() {this.setState({tip: 'The load button triggers:${ this.state.trigerTimes }This.state. TrigerTimes +1})}} Class Load extends Component {constructor(props){super(props); }render() {return (
        <Fragment>
            <LoadMoreButton   />
        </Fragment>
    );
  }

}
const container = document.getElementById('root');

ReactDOM.render(<Load  />, container);
Copy the code

The effect is shown below

lodash.throttled

import React, { Fragment, Component } from 'react';      
import ReactDOM from 'react-dom';


class LoadMoreButton extends Component {
  constructor(props) {
    super(props);
  
    this.state = {
      tip: "", trigerTimes: 1 } this.handleLoadTime = this.handleLoadTime.bind(this); this.handleClick = this.handleClick.bind(this); this.handleClickThrottled = this.throttle(this.handleClick, 1000); // Pass the trigger event handler as the first argument, and the second argument is the time of the interval, in this case 1 second}render() {

    return(
        <Fragment>
              <div><button  onClick={ this.handleClickThrottled }>Load More</button></div>
              <div>{ this.state.tip }</div>
        </Fragment>
    ) 
  }

  handleLoadTime() {/ / this. SetState ((prevState) = > ({/ / tip: ` load button triggered:${prevState.trigerTimes}Times', // trigerTimes: prevState.trigerTimes+1 //})) // equivalent to the following this.setState({tip: 'Load button triggered:${ this.state.trigerTimes }} // Event handler functionhandleClick() { this.handleLoadTime(); } // Throttle (method, duration){// If any method is executed in the current interval, set a switch to identify var runFlag =false; // Return an event handlerreturn function(e) {// Check whether there is a method to execute, if there is, do nothing, iftrue, then jump outif(runFlag){
              return false; } // Start running runFlag =true; // Add a timer to reset the lock state when the interval is reachedsetTimeout(function(){ method(e); // When the execution is complete, declare that no method is currently executing, so that the next time to call runFlag =false;
            }, duration)
          }
  } 
}

class Load extends Component {
  constructor(props){
    super(props);
   
  }

  render() {return (
        <Fragment>
            <LoadMoreButton />
        </Fragment>
    );
  }
}

const container = document.getElementById('root');

ReactDOM.render(<Load  />, container);
Copy the code

You can try not to add throtte functions and throttle-throttled functions to the lodash.throttled library. You’ll see that when you click a button, it will fire event handlers as many times as you click it. If it’s a form submission button, using throttling functions will optimize your code

The effect of throttling without function is as follows:

React functions are throttled. Similarly,React can be implemented with the help of a third-party library, loadsh.debounce

You still need to install the third-party library in NPM or CNPM or YARN mode

NPM I -s loadsh.debounce or CNPM install -s loadsh.debounceCopy the code

If it is installed, check the dependencies of pageckage.json in the root directory to see if it is loadsh.debounce

The following is an example of an input box that verifies the mobile phone number:

import React, { Fragment, Component } from 'react';      
import ReactDOM from 'react-dom';


class SearchBox extends Component{
  constructor(props){
    super(props)
    this.state = {
      tip: null,
      trigerTimes: 1
    }
    
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e){
    if(e.target.value){
      this.setState({
          tip: null        
      })
    }
    
  }

  handleKeyUp = (e) => {
    ifValue){this.isphonelegal (e.telget.value) // Judge user input}} isPhoneLegal = (phone) => {const phoneRegexp = /^1([38]\d|5[0-35-9]|7[3678])\d{8}$/ const { trigerTimes } = this.stateif(phoneregexp.test (phone)) {this.setState({tip: 'Phone number matches the rule! `, trigerTimes: 0 }) }else{this.setState({tip: 'Wrong phone number, triggered:${trigerTimes}', trigerTimes: trigerTimes + 1})}render() {
    return (
      <Fragment>
        <div><input  onChange = { this.handleChange } onKeyUp={ this.handleKeyUp} placeholder="Please enter your mobile phone number." /></div>
        <div >
          {this.state.tip}
        </div>
      </Fragment>
    )
  }

}

class Search extends Component{
  render() {return (
      <Fragment>
          <SearchBox  />
      </Fragment>
    );
  }
}

const container = document.getElementById('root');

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

An example of function stabilization using debounce is shown below

import React, { Fragment, Component } from 'react';      
import ReactDOM from 'react-dom';
//import throttle from 'lodash.throttle'; // function throttle import debounce from'lodash.debounce'; Class SearchBox extends Component{constructor(props){super(props) this.state = {tip: null, trigerTimes: 1 } this.handleChange = this.handleChange.bind(this); this.isPhoneLegal = debounce(this.isPhoneLegal, 1000) }componentWillUnmount(){
    this.isPhoneLegal.cancel();
  }

  handleChange(e){
    if(e.target.value){
      this.setState({
          tip: null        
      })
    }
    
  }

  handleKeyUp = (e) => {
    ifValue){this.isphonelegal (e.telget.value) // Judge user input}} isPhoneLegal = (phone) => {const phoneRegexp = /^1([38]\d|5[0-35-9]|7[3678])\d{8}$/ const { trigerTimes } = this.stateif(phoneregexp.test (phone)) {this.setState({tip: 'Phone number matches the rule! `, trigerTimes: 0 }) }else{this.setState({tip: 'Wrong phone number, triggered:${trigerTimes}', trigerTimes: trigerTimes + 1})}render() {
    return (
      <Fragment>
        <div><input  onChange = { this.handleChange } onKeyUp={ this.handleKeyUp} placeholder="Please enter your mobile phone number." /></div>
        <div >
          {this.state.tip}
        </div>
      </Fragment>
    )
  }

}

class Search extends Component{
  render() {return (
      <Fragment>
          <SearchBox  />
      </Fragment>
    );
  }
}

const container = document.getElementById('root');

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

Of course, instead of using the lodash. Debounce library, you can simply package a Debounce in a native way. The code described above is as follows: you just need to lower deboucunce for the event handler this, and the rest of the code remains the same

 this.isPhoneLegal = this.debounce(this.isPhoneLegal, 1000)
Copy the code

Note that the debounce function is placed inside the searchBox component. If the debounce function is outside the component, defined directly with the function declaration, Call the debouce function name directly, with a slight difference. For this common function, you can wrap it in a separate file

To keep this function from being scattered all over the file, as well as function throttling, the following is a package of debounce functions

Debounce (method, duration) {var timer = null; / *return function(){ var that = this, args = arguments; // If a method is executing during an interval between calls, the execution of the method is terminatedif(timer) { clearTimeout(timer); } // start the call timer =setTimeout(function(){ method.apply(that,args); }, duration)}*/ // abovereturnAnonymous functions can be used as Es6 arrow functions, the following is equivalent to the above, the simplest way to write, but not as easy to understand as the above codereturn(... args) => { clearTimeout(timer); timer =setTimeout(() => method(... args), duration) } }Copy the code

Of course, for the above code, or can be optimized, for the callback function, in Es6, often used to handle the arrow function, this will save a lot of trouble for example: this pointing problem as shown in the following :debouce function is the easiest package

You can also set the timer initial value in the debouce function as a third parameter, which is also ok

debounce(method, duration, timer = null) {
          return(... args) => { clearTimeout(timer); timer =setTimeout(() => { method(... args) }, duration) } }Copy the code

If you want to package your throttle and debounce functions, you can package them in a separate file and expose them to the public. Import them where you want to use them. Call them directly in your code to create a throttle.js file in the root directory (your own) via export Default exposed

/* * @authors chuanchuan ([email protected]) * @id suibichuanji * @date 2019-08-24 19:08:17 * @wechatnum @desc Encapsulates the throttling function * @param method,duration:method event handler,duration: interval time * @returnAnonymous functions * Principle: By judging whether a certain time to trigger function, * if not use the timer to delay time, and the next event will be reset timer * interval, it is no matter how frequent event triggers a * will ensure execute within the provisions of the event will be a true event handler * * /functionthrottle(method, duration) { var timer = null; var prevTime = new Date(); // The previous timereturn function() {var that = this, currentTime = new Date(), resTime = currentTime-prevTime; // Time stamp // Prints the time difference between the current world and the last world console.log("Time difference", resTime); // The time since the last execution is shorter than the set intervalif(resTime < duration) {// Clear the last timer, cancel the last queue task, and reset the timer. This ensures that the function is fired only once within 500 ms seconds, achieving the purpose of function throttling clearTimeout(timer); timer =setTimeout(function() {
          prevTime = currentTime;
          method.apply(that);
        }, duration)
      } elsePrevTime = currentTime; prevTime = currentTime; prevTime = currentTime; method.apply(that); }}}export default throttle;

Copy the code

It is then introduced in the need to use function throttling file

import throttle from './throttle'; / / within the constructor of the component initialization, this bad. This binding for call handleClickThrottled = throttle (this handleClick, 1000);Copy the code

Similarly, if you package the debounce function itself, separate it out and package it as a function, which is exposed by export and can be called elsewhere

/** ** @authors Chuan Chuan ([email protected]) * @id suibichuanji * @date 2019-08-24 19:08:17 * @wechatnum wechat public account: Itclancoder *  @version$Id@param {method} Duration} method is the event handler,duration is the delay time This way, only the last operation of the event handler function is actually triggered. * * This is usually used for input field events. Common scenarios are form searches or associative queries. * If you do not use anti - shake will continuously send requests, increasing the pressure on the server * after using anti - shake, will send requests after the user input the keywords to query, Baidu search is so realized */function  debounce(method, duration) {
          var timer = null;
         return function(){ var that = this, args = arguments; // If a method is executing during an interval between calls, the execution of the method is terminatedif(timer) { clearTimeout(timer); } // start the call timer =setTimeout(function(){
              method.apply(that,args);
            }, duration)

          }

  }

  export default debounce;
Copy the code

Summary:

How do you throttle and defend against tremors in React

  • Refer to the throttle function of the lodash.throttle third-party library
  • Encapsulate your own throttle function for throttling
  • Refer to lodash. Debounce for debounce
  • Encapsulate the Debounce function for shock protection

conclusion

How to prevent functions from being called too quickly (function throttling, two ways) or too many times (function buffering)

The function of throttling and shaking is a means of front-end performance improvement, although a few lines of code, but the interview, often asked, let you write, many times, pat chest, without the help of search, you really can not write out

In the actual development, function throttling and function shaking is more frequent, so its importance is self-evident