@rooks/use-on-window-resize
Version:
A React hook for window on resize event
80 lines (73 loc) • 3 kB
JavaScript
import { useEffect, useLayoutEffect, useRef } from 'react';
/**
* useIsomorphicEffect
* Resolves to useEffect when "window" is not in scope and useLayout effect in the browser
* @param {function} callback Callback function to be called on mount
*/
const useIsomorphicEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
/**
* useFreshRef
* @param value The value which needs to be fresh at all times. Probably
* best used with functions
* @param preferLayoutEffect Should the value be updated using a layout effect
* or a passive effect. Defaults to false.
* @returns A ref containing the fresh value
*/
function useFreshRef(value, preferLayoutEffect = false) {
const useEffectToUse = preferLayoutEffect ? useIsomorphicEffect : useEffect;
const ref = useRef(value);
useEffectToUse(() => {
ref.current = value;
});
return ref;
}
function useFreshTick(callback) {
const freshRef = useFreshRef(callback);
function tick(...args) {
if (freshRef && typeof freshRef.current === "function") {
freshRef.current(...args);
}
}
return tick;
}
/**
* useGlobalObjectEventListener hook
*
* A react hook to an event listener to a global object
*
* @param {Window|Document} globalObject The global object to add event onto
* @param {string} eventName The event to track
* @param {function} callback The callback to be called on event
* @param {object} conditions The options to be passed to the event listener
* @param {boolean} when Should the event listener be active
* @param {boolean} isLayoutEffect Should it use layout effect. Defaults to false
* @return {undefined}
*/
function useGlobalObjectEventListener(globalObject, eventName, callback, listenerOptions = {}, when = true, isLayoutEffect = false) {
const freshCallback = useFreshTick(callback);
const { capture, passive, once } = listenerOptions;
const useEffectToRun = isLayoutEffect ? useIsomorphicEffect : useEffect;
useEffectToRun(() => {
if (typeof globalObject !== "undefined" && globalObject.addEventListener && when) {
globalObject.addEventListener(eventName, freshCallback, listenerOptions);
return () => {
globalObject.removeEventListener(eventName, freshCallback, listenerOptions);
};
}
}, [eventName, capture, passive, once]);
}
/**
*
* useOnWindowResize hook
*
* Fires a callback when window resizes
*
* @param {function} callback Callback to be called before unmount
* @param {boolean} when When the handler should be applied
* @param {boolean} isLayoutEffect Should it use layout effect. Defaults to false
*/
function useOnWindowResize(callback, when = true, isLayoutEffect = false) {
useGlobalObjectEventListener(window, "resize", callback, { passive: true }, when, isLayoutEffect);
}
export default useOnWindowResize;
//# sourceMappingURL=index.esm.js.map