Skip to content

Instantly share code, notes, and snippets.

@idiotWu
Last active October 6, 2017 15:22
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save idiotWu/76824adb9159efdc2afa2281d8a02fa2 to your computer and use it in GitHub Desktop.
Save idiotWu/76824adb9159efdc2afa2281d8a02fa2 to your computer and use it in GitHub Desktop.
attach-events decorator for react
/**
* @decorator
* Attach events to DOM element
*
* @param {Element|Function} elemOrFunc: DOM Element, or a function returns element
* @param {String} events: a list events separated with ','
*
* Usage:
* @attachEvents(window, 'click')
* handleWindowClick(evt) {
* ...
* }
*
* @attachEvents(document, 'mousedown, touchstart')
* handlePointerDown(evt) {
* ...
* }
*
* @attachEvents(function getElem() { return this.refs.elem; }, 'click')
* handleClickOnElem(evt) {
* ...
* }
*/
const noop = () => {};
export function attachEvents(elemOrFunc, events) {
const eventList = events.split(/\s*,\s*/);
const getElem = typeof elemOrFunc === 'function' ? elemOrFunc : () => elemOrFunc;
return function decorator(proto, method, descriptor) {
const {
componentDidMount = noop,
componentWillUnmount = noop,
} = proto;
const symbolHandler = Symbol(method);
function addListener() {
const elem = getElem.call(this);
const handler = this[symbolHandler] = (...args) => {
descriptor.value.apply(this, args);
};
eventList.forEach((evt) => {
elem.addEventListener(evt, handler);
});
}
function removeListener() {
const elem = getElem.call(this);
eventList.forEach((evt) => {
elem.removeEventListener(evt, this[symbolHandler]);
});
}
// eslint-disable-next-line no-param-reassign
proto.componentDidMount = function componentDidMountWrapped() {
componentDidMount.call(this);
addListener.call(this);
};
// eslint-disable-next-line no-param-reassign
proto.componentWillUnmount = function componentWillUnmountWrapped() {
componentWillUnmount.call(this);
removeListener.call(this);
};
};
}
@abruzzihraig
Copy link

Could add a parameter to prevent decorating for using it on different situation. e.g. different devices.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment