user12356906
user12356906

Reputation:

Higher Order Component (HOC) and window resize listener

I have the following HOC and I thought about creating 3 states where these would be my breakpoints

But I'm wondering how I could set these states to true when a breakpoint is reached example:

and then when one of these breakpoins was reached the state would change to true

Also how I could do to pass only one state (whichever is true) at the moment in my HOC?

Can I improve this logic?

import React from "react";

const withWindowResize = Component => {
  class WrappedComponent extends React.Component {
    constructor(props) {
      super(props);

      this.state = {
        height: 0,
        width: 0,
        mobile: false,
        desktop: false,
        tablet: false
      };
      window.addEventListener("resize", this.resizeUpdate);
    }

    componentDidMount() {
      this.update();
    }

    resizeUpdate = () => {
      this.setState({
        height: window.innerHeight,
        width: window.innerWidth
      });
    };

    render() {
      return <Component />;
    }
  }
  return WrappedComponent;
};

export default withWindowResize;

Upvotes: 0

Views: 897

Answers (1)

Michalis Garganourakis
Michalis Garganourakis

Reputation: 2930

There are plenty of ways to do it, but following your approach, you could do something like the following, where you just have a size variable on your state changing based on the specs you provided above.

In that way, you just have to pass this.state.size to your component.

import React from "react";

const withWindowResize = Component => {
  class WrappedComponent extends React.PureComponent {
    constructor(props) {
      super(props);

      this.state = {
        size: this.findSize()
      };
    }

    componentDidMount() {
      window.addEventListener("resize", this.resizeUpdate.bind(this)); // initialize your listener
    }

    componentWillUnmount() { // remove event listener on component unmount
      window.removeEventListener("resize", this.resizeUpdate.bind(this));
    }

    findSize() {
      return window.innerWidth > 1919
          ? "large"
          : window.innerWidth > 992
          ? "desktop"
          : window.innerWidth > 768
          ? "tablet"
          : "mobile"; // find currentSize
    }

    resizeUpdate() {
      const currentSize = this.findSize();

      this.setState({
        size: currentSize
      });
    }

    render() {
      return <Component size={this.state.size} />;
    }
  }

  return WrappedComponent;
};

export default withWindowResize;

Notice I'm using React.PureComponent as we don't want to change our state and re-render our Component on every window resize.

This will be the same as using React.Component and checking right before the use of this.setState, if our currentSize is different from the one we have on state, before updating it.

if (currentSize !== this.state.size) {
  this.setState({
    size: currentSize
  });
}

Upvotes: 1

Related Questions