Home > Mobile >  React, state change not reflected in callback function
React, state change not reflected in callback function

Time:08-24

Im new to React and stumbled across an issue I don't understand and can't resolve. I want to change an internal block size dynamically upon specific window screen width threshold cross.

Here is a sample code I prepared:

function X(title) {
  const [myWidth, setMyWidth] = React.useState(200)   
  
  function onResize(){
    if(innerWidth > 1000 && myWidth <= 200){
      console.log(`Make Bigger: `, myWidth)
      setMyWidth(400)
    } else if( innerWidth <= 1000 && myWidth >= 400) {
      console.log(`Make Smaller: `, myWidth)
      setMyWidth(200)
    }
  }
  
  React.useEffect(()=>{
    console.log("HELLO")
    addEventListener('resize', onResize)
  },[])
  
  return (<div>
      <div style={{
          backgroundColor:'red',
          width: myWidth,
          height: 100
        }}>
        Hello
      </div>
    </div>);
}

const el = document.querySelector("#root");
ReactDOM.render(<X title='Example Component' />, el);

I want to see the div block width increase when the innerWidth become greater than 1000 and decrease when the innerWidth get lower than 1000 BUT I don't want to see the console messages on every listener callback invocation (i.e. every pixel change in the width of the screen).

https://codepen.io/radoslavmarino7/pen/KKoYNWK?editors=0011

CodePudding user response:

Probably using media queries approach is a better.

Check this simple implementation.

.box {
  background: red;
  height: 100px;
  display: block;
}

@media only screen and (max-width: 1000px) {
  .box {
    width: 200px;
  }
}

@media only screen and (min-width: 1000px) {
  .box {
    width: 400px;
  }
}
<div ></div>

CodePen

Documentation

Here is the React approach, you should include useEffect dependencies, like this:

React.useEffect(()=>{
    console.log("HELLO")
    window.addEventListener('resize', onResize);
    return () => {
      window.removeEventListener('resize', onResize);
    };
  },[myWidth, setMyWidth])

CodePen

Documentation

CodePudding user response:

There is no problem with having the callback being called for every pixel change: given that most of the time the state itself doesn't change, React won't rerender, so it shouldn't really affect performance. But media queries are indeed probably a better option.

CodePudding user response:

You can wrap your function onResize with a debounce and set a timeout. This way the function onResize with return an output only after user has stopped performing the action.

  • Related