Skip to content

Instantly share code, notes, and snippets.

@burdiuz
Last active October 31, 2021 22:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save burdiuz/bc1f33087284f8392b9d9589f0468cbb to your computer and use it in GitHub Desktop.
Save burdiuz/bc1f33087284f8392b9d9589f0468cbb to your computer and use it in GitHub Desktop.
React hook that returns window size and initiates render when window size is being changed.

@actualwave/use-window-size

This package is more of an experiment, if you need such hook, better look for alternatives.

React hook useWindowSize() that returns Window's innerWidth and innerHeight properties, and initiates render when window is being resized. It uses single "resize" listener and relies on WeakSet and WeakRef, so be sure you can use it. Here is an example on CodeSandbox.

export declare const getCurrentWindow = () => Window;
export declare const getLatestWindowSize = (win?: Window) => {
innerWidth: number,
innerHeight: number
};
export declare const useWindowSize = () => {
innerWidth: number,
innerHeight: number
};
import { useState } from 'react';
const getWindow = () => {
try {
const testAccess = window.top.innerWidth;
return window.top;
} catch (error) {
return window;
}
};
const register = new WeakSet();
let currentWindow;
let latestSize;
let head = null;
export const getCurrentWindow = () => {
if (!currentWindow) {
currentWindow = getWindow();
}
return currentWindow;
};
export const getLatestWindowSize = ({
innerWidth,
innerHeight
} = currentWindow) => ({
innerWidth,
innerHeight
});
const setupListener = () =>
currentWindow.addEventListener('resize', () => {
latestSize = getLatestWindowSize();
let prev = null;
let current = head;
while (current) {
const setSize = current.handler.deref();
if (setSize) {
setSize(latestSize);
prev = current;
} else if (prev) {
prev.next = current.next;
} else {
head = current.next;
}
current = current.next;
}
});
const initialize = () => {
if (latestSize) {
return;
}
getCurrentWindow();
latestSize = getLatestWindowSize();
setupListener();
};
export const useWindowSize = () => {
initialize();
const [, setSize] = useState(latestSize);
if (!register.has(setSize)) {
register.add(setSize);
head = { handler: new WeakRef(setSize), next: head };
}
return latestSize;
};
{
"name": "@actualwave/use-window-size",
"version": "0.0.3",
"description": "React hook that returns window size and initiates render when window size has been changed.",
"main": "index.js",
"module": "index.js",
"types": "index.d.ts",
"keywords": [
"react",
"window",
"size",
"resize",
"event",
"hook"
],
"peerDependencies": {
"react": ">=16.8.0"
},
"homepage": "https://gist.github.com/burdiuz/bc1f33087284f8392b9d9589f0468cbb",
"bugs": {
"url": "https://gist.github.com/burdiuz/bc1f33087284f8392b9d9589f0468cbb",
"email": "burdiuz@gmail.com"
},
"license": "MIT",
"author": "Oleg Galaburda <burdiuz@gmail.com> (http://actualwave.com/)"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment