Tracks the current window scroll position.
import { useWindowScroll } from "@/hooks/browser/use-window-scroll"; const Component = () => { const { x, y } = useWindowScroll(); return ( <div> <p>Window Scroll X: {x}</p> <p>Window Scroll Y: {y}</p> </div> );};
npx atmx add hook use-window-scroll
Copy and paste the following method into @/utils/helpers/undefined.ts:
@/utils/helpers/undefined.ts
import * as React from "react"; import { useRafState } from "@/hooks/use-raf-state.ts";import { isBrowser } from "@/helpers/is-browser.ts"; export interface WindowScrollState {x: number;y: number;} /*** Tracks the current window scroll position.** @returns The current window scroll position.** @example* ```tsx* import { useWindowScroll } from "@/hooks/browser/use-window-scroll";** const Component = () => {* const { x, y } = useWindowScroll();** return (* <div>* <p>Window Scroll X: {x}</p>* <p>Window Scroll Y: {y}</p>* </div>* );* };* ```*/const useWindowScroll = (): WindowScrollState => {const browser = isBrowser(); const [state, setState] = useRafState<WindowScrollState>(() => ({x: browser ? window.scrollX : 0,y: browser ? window.scrollY : 0,})); React.useEffect(() => {const handler = () => { setState((state) => { const { scrollX, scrollY } = window; // Check state for change, return same state if no change happened to prevent rerender // (see useState/setState documentation). useState/setState is used internally in useRafState/setState. return state.x !== scrollX || state.y !== scrollY ? { x: scrollX, y: scrollY } : state; });}; // We have to update window scroll at mount, before subscription.// Window scroll may be changed between render and effect handler.handler(); window.addEventListener("scroll", handler, { capture: false, passive: true,}); return () => { window.removeEventListener("scroll", handler);};}, []); return state;}; export default useWindowScroll;