Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

debounce on react got e.target.value undefined

Was trying to debounce an input using lodash's debounce, but below code gave me value of undefined.

const { debounce } from 'lodash'

class App extends Component {

  constructor(){
    super()
    this.handleSearch = debounce(this.handleSearch, 300)
  }

  handleSearch = e => console.log(e.target.value)

  render() {
    return <input onChange={e => this.handleSearch(e)} placeholder="Search" />
  }

}
like image 338
Sharon Chai Avatar asked Mar 03 '18 05:03

Sharon Chai


1 Answers

This happens because of event pooling on the React side.

The SyntheticEvent is pooled. This means that the SyntheticEvent object will be reused and all properties will be nullified after the event callback has been invoked. This is for performance reasons. As such, you cannot access the event in an asynchronous way.

function debounce(func, wait, immediate) {
	var timeout;
	return function() {
		var context = this, args = arguments;
		var later = function() {
			timeout = null;
			if (!immediate) func.apply(context, args);
		};
		var callNow = immediate && !timeout;
		clearTimeout(timeout);
		timeout = setTimeout(later, wait);
		if (callNow) func.apply(context, args);
	};
};

class App extends React.Component {

  constructor() {
    super()
    this.handleSearch = debounce(this.handleSearch, 2000);
  }

  handleSearch(event) {
    console.log(event.target.value);
  }

  render() {
    return <input onChange = {
      (event)=>{event.persist(); this.handleSearch(event)}
    }
    placeholder = "Search" / >
  }

}

ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

https://reactjs.org/docs/events.html#event-pooling

like image 104
Agney Avatar answered Oct 10 '22 17:10

Agney