0

I have a React Hook for setting the window size on a resize but it doesn't seem to be updating. Can anyone shed some light on why this doesn't work and also how you would use this hook in another component to set a Boolean for checking if the window size is within a mobile range? First of all, this is the hook:

    import { useState, useEffect } from 'react';

type WindowSize = {
  width: number,
  height: number,
};

export const useWindowSize = (): WindowSize => {
  const [windowSize, setWindowSize] = useState<WindowSize>({
    width: 0,
    height: 0,
  });

  useEffect(
    () => {
      function handleResize() {
        setWindowSize({
          width: window.innerWidth,
          height: window.innerHeight,
        });
        console.log(`resizing: width = ${windowSize.width} / height = ${windowSize.height}`);
        // console.log(`resizing: width = ${window.innerWidth} / height = ${window.innerHeight}`);
      }

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

  return windowSize;
};

and in my app I have a const variable set for the hook:

const {width, height} = useWindowSize();

Initially, I noticed that this was always only being set once on the app launch (and sometimes it was just {0,0}). But then I noticed that the hook itself wasn't updating internally on the window resize.

Any ideas?

Lee Probert
  • 10,308
  • 8
  • 43
  • 70

1 Answers1

1

Its working as expected you just logging stale values.

The stale values are due to closure on windowSize value in handleResize scope that assigned to addEventListener callback.

See the right results by logging from useEffect:

export const useWindowSize = (): WindowSize => {
  const [windowSize, setWindowSize] = useState<WindowSize>({
    width: window.innerWidth,
    height: window.innerHeight
  });

  useEffect(() => {
    console.log(windowSize);
  }, [windowSize]);

  useEffect(() => {
    function handleResize() {
      setWindowSize({
        width: window.innerWidth,
        height: window.innerHeight
      });
    }

    window.addEventListener("resize", handleResize);
    handleResize();
    return () => window.removeEventListener("resize", handleResize);
  }, []);

  return windowSize;
};
Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
  • Yes, this was it. I am just not seeing my `isMobile` boolean propagating through my component stack. Thanks for the help. – Lee Probert Apr 28 '22 at 11:35
  • Also notice that `handleResize()` call in `useEffect` is redundant and equivalent to the initial values you provide in `useState`. – Dennis Vash Apr 28 '22 at 11:36