Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I prevent component rerendering on browser resize?

Tags:

reactjs

In main layout component there is 2 different component which is MobileHeader and DesktopHeader when resize the browser it rerender these components every resize action. How to stop to render again and again when resize the browser ?

function useWindowSize() {
  const [size, setSize] = useState([0, 0]);
  useLayoutEffect(() => {
    function updateSize() {
      setSize([window.innerWidth, window.innerHeight]);
    }
    window.addEventListener('resize', updateSize);
    updateSize();
    return () => window.removeEventListener('resize', updateSize);
  }, []);
  return size;
}

const MainLayout = () => {
     const [w,h] = useWindowSize();
     return(
       <>
         {w > 992 ? <DesktopHeader/> : <MobileHeader/>}
       </>
     )
}
like image 402
mrtyvz61 Avatar asked Sep 01 '25 10:09

mrtyvz61


2 Answers

I would just debounce the updateSize function so the "resize" handler calls that instead and doesn't wail on your React component state updates.

Using a debouncing utility from a tried and tested library is probably best, i.e. debounce from lodash. I'm using a 200ms delay, but obviously you should test this and tune this delay value to suit your needs.

import { debounce } from 'lodash';

function useWindowSize() {
  const [size, setSize] = useState([0, 0]);

  useLayoutEffect(() => {
    function updateSize() {
      setSize([window.innerWidth, window.innerHeight]);
    }

    const debouncedUpdateSize = debounce(updateSize, 200);

    window.addEventListener('resize', debouncedUpdateSize);
    updateSize();
    return () => window.removeEventListener('resize', debouncedUpdateSize);
  }, []);

  return size;
}

If you don't want to add another dependency to your project you can roll your own simple debounce utility function.

const debounce = (fn, delay) => {
  let timerId;
  return (...args) => {
    clearTimeout(timerId);
    timerId = setTimeout(fn, delay, [...args]);
  };
};
like image 59
Drew Reese Avatar answered Sep 03 '25 00:09

Drew Reese


React will re-render your component when there is a change in state/props of the component. Your component is dependent on the window's dimension(width, height), so for every change on these dimensions, react will re-render the component.

You can use user make use of throttling/ debouncing based on your use case. Or simply you can integrate timeout.

Moreover, You can simply use the below javascript to identify the mobile devices and get rid of all these complex calculations.

if( /Android|webOS|iPhone|iPad|Mac|Macintosh|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
 // some code..
}
like image 43
Dhruvi Makvana Avatar answered Sep 02 '25 23:09

Dhruvi Makvana