0

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.

Community
  • 1
  • 1
Dan
  • 2,830
  • 19
  • 37
  • Interesting question, but not quite sure what you're looking for. You just want to call an arbitrary method on the component, rather than the hard coded `onResize`? – bjudson Dec 09 '16 at 05:24
  • Right. I suppose what I'd like is for the base component to be able to subscribe to the HOC event emission, in a sort of listener pattern, i.e. passing back the handler (re-rendering being one handler option), rather than passing back the event. Is this inherently wrong to ask? – Dan Dec 09 '16 at 05:58
  • The more I think about it, I don't see why just passing a prop, and letting that prop change be the trigger isn't the obvious solution. So the HOC simply adds listeners, and adds a prop to the child element that is some result of those listeners. The child element re-renders when the prop changes. Done. – Dan Dec 09 '16 at 06:10

0 Answers0