Post by Peter Watson-Wailes

In my day to day, I deal with a lot of React code. One of the most common components I use across the codebase I maintain is a table with search and sorting options.

The sorting runs onClick immediately, but the tables (generated from JSON) can often run into 10k+ rows of data, at which point running on every keypress is a pain. The way we get around that is by using a debounce.

The code for a basic version of this is shown below. Hopefully it's helpful to someone out there!

The Debounce Function

This is a nice little debouncer which runs in a nicely performant manner.

function debounce(a,b,c){var d,e;return function(){function h(){d=null,c||(e=a.apply(f,g))}var f=this,g=arguments;return clearTimeout(d),d=setTimeout(h,b),c&&!d&&(e=a.apply(f,g)),e}}

Debouncing Events

Now, here's two implementations of the component code.

ES5

var Table = React.createClass({ getInitialState: function (props) { return { searchTerm: props.searchTerm } }, componentWillMount: function() { this.setSearchTerm = debounce(this.method, 1000) }, setSearchTerm: function (e) { this.setState({ searchTerm: e.target.value }) }, render: function () { return ( <div> <p>{this.state.searchTerm}</p> <input type="search" onChange={this.setSearchTerm} /> </div> ) } })

ES6

class Table extends React.Component { constructor (props) { super(props) this.state = { searchTerm: props.searchTerm } } setSearchTerm = debounce((e) => { this.setState({ searchTerm: e.target.value }) }, 1000) render() { return ( <div> <p>{this.state.searchTerm}</p> <input type="search" onChange={this.setSearchTerm} /> </div> ) } }

Demo

You can see a demo of the ES6 example running at this JSfiddle.

If you've enjoyed this post, you might want to follow me on Twitter