4

I'm building a photo gallery in react js. Obviously it's going to have to be responsive and I've tackled this by setting values like so in the component's render method:

let thumbWidth = window.innerWidth >= 480 ? 75 : 100;

The problem is that I need the const value to change when the window is resized. My my first attempts was to build a function like so and bind it in the constructor:

getThumbWidth = (vpWidth) => {
    if(vpWidth >= 480 ) {
        this.setState({thumbSize: 120}); 
     } else {
        this.setState({thumbSize: 50}); 
     }
}

This worked in terms of setting the variable's initial value but how do I trigger the function when the window resizes?

Have tried adding a resize function:

resize = () => this.getThumbWidth()

...and then changing getThumbWidth so that it sets the value in the component's sate - the idea being that when state is updated the component automatically rerenders:

getThumbWidth = (vpWidth) => {
    if(vpWidth >= 480 ) {
        this.setState({thumbSize: 120}); 
     } else {
        this.setState({thumbSize: 50}); 
     }
}

And then calling it via lifecycle methods as suggested in several other solutions but the event listener does not appear to be firing:

componentDidMount() {
    window.addEventListener('resize', this.resize)
}

componentWillUnmount() {
    window.removeEventListener('resize', this.resize)
}  

Still not working though... any ideas?

4
  • 1
    This alone won't solve the question, but, if you want to change value of a variable, why is it defined as a constant in the first place? Hint is in the name, const is constant - in other words, constant things do not change, they stay the same. Why not use let instead - acts as a same block-scoped variable like const does, only the values can change. Commented Aug 27, 2018 at 11:11
  • 1
    better change const to another type Commented Aug 27, 2018 at 11:15
  • Thanks - I spotted that and have changed it - will edit question to reflect this. Commented Aug 27, 2018 at 11:15
  • In getThumbWidth there's a parameter but when you call it you don't pass this parameter resize = () => this.getThumbWidth() Commented Aug 27, 2018 at 11:19

3 Answers 3

16

@Jousi, try this below code works fine of window resize

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      windowSize: "",
      thumbWidth: 75
    };
  }

  handleResize = e => {
    const windowSize = window.innerWidth;
    const thumbWidth = (windowSize >= 480 && 100) || 75;
    this.setState(prevState => {
      return {
        windowSize,
        thumbWidth
      };
    });
  };

  componentDidMount() {
    window.addEventListener("resize", this.handleResize);
  }

  componentWillUnmount() {
    window.removeEventListener("resize", this.handleResize);
  }

  render() {
    return (
      <div>
        <h2>window size: {this.state.windowSize}</h2>
        <h3>thumbnail width: {this.state.thumbWidth}</h3>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
Sign up to request clarification or add additional context in comments.

1 Comment

There is mistake in this answer: should use proper componentWillUnmount, instead of componentWillMount, when removing event listener.
1

U can add ref attribute to container of your component:

return (
    <div
       className={mainClass}
       ref={(elem) => { this.elem = elem; }}
    >
        your gallery here
   </div>

Then in your componentDidMount u have access to all events connected to your container. Then u can invoke your function depending on changes on these events. For example:

componentDidMount() {
   const parent = this.elem.parentNode;
       if (parent.scrollHeight > parent.clientHeight) {
         parent.onscroll = (() => this.yourMethod(parent));
       } 
}

Comments

0

I think you might need to initialise the this.resize function.

like so: window.removeEventListener('resize', this.resize())

1 Comment

This is incorrect, you shouldn't be invoking this.resize, you should just be passing the reference itself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.