Over on this question, it is answered how to bind a component to browser resize events. I'd like to create an HOC/decorator function to elegantly add this behaviour to Components in my Component Library so that I can be dry about adding this behaviour.
I was able to use the inverted HOC pattern to create a higher-order-component that will essentially attach the base components onResize
method to a (resize) event listener:
import React from 'react';
import debounce from 'debounce';
import getDisplayName from 'recompose/getDisplayName'
export const withOnResize = BaseComponent => (
class ResizeEnhanced extends BaseComponent {
static displayName = getDisplayName(BaseComponent);
componentWillMount() {
this.debounce = debounce(this.onResize, 200);
window.addEventListener('resize', this.debounce);
if (super.componentWillMount) super.componentWillMount();
}
componentWillUnmount() {
window.removeEventListener('resize', this.debounce);
if (super.componentWillUnmount) super.componentWillUnmount();
}
render() {
return super.render();
}
}
);
and then the usage in some other component file:
export default withOnResize(MyComponent); // MyComponent has an onResize method.
--
This is sub-optimal at least because there is a dodgy reliance on the base component having an onResize method.
Is there a functional approach that would allow easily connecting resize listener and lifecycle events to a method on base components?
Obviously another option is to use something like Redux, and build the global events into the store - dispatching as required. Or even context if I was willing to re-render my entire app on context change, but I'm more interested in doing this at the component decoration level at this stage.