Lee Probert
Lee Probert

Reputation: 10859

React Hook for window resize doesn't update

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?

Upvotes: 0

Views: 2414

Answers (1)

Dennis Vash
Dennis Vash

Reputation: 53984

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;
};

Upvotes: 1

Related Questions