Perform debounce in React.js

前端 未结 30 1556
礼貌的吻别
礼貌的吻别 2020-11-22 04:11

How do you perform debounce in React.js?

I want to debounce the handleOnChange.

I tried with debounce(this.handleOnChange, 200) but it doesn\'t

相关标签:
30条回答
  • 2020-11-22 04:37

    Did you try?

    function debounce(fn, delay) {
      var timer = null;
      return function() {
        var context = this,
          args = arguments;
        clearTimeout(timer);
        timer = setTimeout(function() {
          fn.apply(context, args);
        }, delay);
      };
    }
    
    var SearchBox = React.createClass({
      render: function() {
        return <input type="search" name="p" onChange={this.handleOnChange} />;
      },
    
      handleOnChange: function(event) {
        debounce(\\ Your handleChange code , 200);
      }
    });
    
    0 讨论(0)
  • 2020-11-22 04:39

    Julen solution is kind of hard to read, here's clearer and to-the-point react code for anyone who stumbled him based on title and not the tiny details of the question.

    tl;dr version: when you would update to observers send call a schedule method instead and that in turn will actually notify the observers (or perform ajax, etc)

    Complete jsfiddle with example component jsfiddle

    var InputField = React.createClass({
    
        getDefaultProps: function () {
            return {
                initialValue: '',
                onChange: null
            };
        },
    
        getInitialState: function () {
            return {
                value: this.props.initialValue
            };
        },
    
        render: function () {
            var state = this.state;
            return (
                <input type="text"
                       value={state.value}
                       onChange={this.onVolatileChange} />
            );
        },
    
        onVolatileChange: function (event) {
            this.setState({ 
                value: event.target.value 
            });
    
            this.scheduleChange();
        },
    
        scheduleChange: _.debounce(function () {
            this.onChange();
        }, 250),
    
        onChange: function () {
            var props = this.props;
            if (props.onChange != null) {
                props.onChange.call(this, this.state.value)
            }
        },
    
    });
    
    0 讨论(0)
  • 2020-11-22 04:40

    Instead of wrapping the handleOnChange in a debounce(), why not wrap the ajax call inside the callback function inside the debounce, thereby not destroying the event object. So something like this:

    handleOnChange: function (event) {
       debounce(
         $.ajax({})
      , 250);
    }
    
    0 讨论(0)
  • 2020-11-22 04:41

    After struggling with the text inputs for a while and not finding a perfect solution on my own, I found this on npm: react-debounce-input.

    Here is a simple example:

    import React from 'react';
    import ReactDOM from 'react-dom';
    import {DebounceInput} from 'react-debounce-input';
    
    class App extends React.Component {
    state = {
        value: ''
    };
    
    render() {
        return (
        <div>
            <DebounceInput
            minLength={2}
            debounceTimeout={300}
            onChange={event => this.setState({value: event.target.value})} />
    
            <p>Value: {this.state.value}</p>
        </div>
        );
    }
    }
    
    const appRoot = document.createElement('div');
    document.body.appendChild(appRoot);
    ReactDOM.render(<App />, appRoot);
    

    The DebounceInput component accepts all of the props you can assign to a normal input element. Try it out on codepen

    I hope it helps someone else too and saves them some time.

    0 讨论(0)
  • 2020-11-22 04:41

    Extend useState hook

    import { useState } from "react";
    import _ from "underscore"
    export const useDebouncedState = (initialState, durationInMs = 500) => {
        const [internalState, setInternalState] = useState(initialState);
        const debouncedFunction = _.debounce(setInternalState, durationInMs);
        return [internalState, debouncedFunction];
    };
    export default useDebouncedState;
    

    Use hook

    import useDebouncedState from "../hooks/useDebouncedState"
    //...
    const [usernameFilter, setUsernameFilter] = useDebouncedState("")
    //...
    <input id="username" type="text" onChange={e => setUsernameFilter(e.target.value)}></input>
    

    https://trippingoncode.com/react-debounce-hook/

    0 讨论(0)
  • 2020-11-22 04:42

    a little late here but this should help. create this class(its written in typescript but its easy to convert it to javascript)

    export class debouncedMethod<T>{
      constructor(method:T, debounceTime:number){
        this._method = method;
        this._debounceTime = debounceTime;
      }
      private _method:T;
      private _timeout:number;
      private _debounceTime:number;
      public invoke:T = ((...args:any[])=>{
        this._timeout && window.clearTimeout(this._timeout);
        this._timeout = window.setTimeout(()=>{
          (this._method as any)(...args);
        },this._debounceTime);
      }) as any;
    }
    

    and to use

    var foo = new debouncedMethod((name,age)=>{
     console.log(name,age);
    },500);
    foo.invoke("john",31);
    
    0 讨论(0)
提交回复
热议问题