-
-
Save abruzzihraig/8ba80965f42c04dedb12fc8572bb30f0 to your computer and use it in GitHub Desktop.
attach-events decorator for react
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @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 ',' | |
* @param {String} preventDecorator: prevent decorate when it doesn't need | |
* | |
* Usage: | |
* @attachEvents(window, 'click') | |
* handleWindowClick(evt) { | |
* ... | |
* } | |
* | |
* @attachEvents(window, 'resize', IS_MOBILE) | |
* 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, preventDecorate) { | |
if (preventDecorate) return function (target, key, descriptor) { return descriptor; }; | |
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); | |
}; | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment