Skip to content

Instantly share code, notes, and snippets.

@DC3
Last active November 27, 2017 18:30
Show Gist options
  • Save DC3/7d50bf79da0552bbde34cca7561dc2e3 to your computer and use it in GitHub Desktop.
Save DC3/7d50bf79da0552bbde34cca7561dc2e3 to your computer and use it in GitHub Desktop.
React controlled component debounce HOC
// usage
// debounceHOC('input', { onChange: 300, onMouseOver: 1e3})
import _ from 'lodash';
import React, {PureComponent} from 'react';
import {findDOMNode} from 'react-dom';
function debounceHOC(Comp, events = {}) {
class debounceEventsComponent extends PureComponent {
constructor(props) {
super(props);
_.bindAll(this, ['_persist']);
}
componentDidMount() {
let node = findDOMNode(this);
if (!node.value) {
node = node.querySelector('[value]');
}
this.node = node;
}
componentWillReceiveProps(np) {
if (!np || !_.isUndefined(np.value)) { return; }
const t = this.node;
if (np.value !== t.value) {
t.value = np.value;
}
}
_persist() {
const e = _.find(arguments, (arg) => !!arg.target);
if (_.isFunction(e.persist)) { e.persist(); }
return {target: this.node};
}
render() {
const {value, defaultValue} = this.props;
const ps = _.omit(this.props, ['value', 'defaultValue']);
const propsWithoutEvents = _.omitBy(ps, _.isFunction);
const propsEvents = _.pickBy(ps, _.isFunction);
const debounceEvents = _.transform(propsEvents, (o, fn, event) => {
if (_.has(events, event)) {
o[event] = _.flow([
this._persist,
_.debounce(fn, events[event])
]);
} else {
o[event] = fn;
}
return o;
}, {});
const props = _.assign(
{}, propsWithoutEvents, debounceEvents,
{defaultValue: value || defaultValue},
);
return React.createElement(Comp, props);
}
}
return debounceEventsComponent;
}
export default debounceHOC;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment