From 874e9a9ba5058e66c248f62a0d04dca8b56387fd Mon Sep 17 00:00:00 2001 From: Ward Oosterlijnck Date: Sat, 23 Mar 2019 16:40:40 +1100 Subject: [PATCH 1/2] useWindowScroll hook --- docs/useWindowScroll.md | 20 ++++++++++++ src/__stories__/useWindowScroll.story.tsx | 30 +++++++++++++++++ src/index.ts | 2 ++ src/useWindowScroll.ts | 39 +++++++++++++++++++++++ 4 files changed, 91 insertions(+) create mode 100644 docs/useWindowScroll.md create mode 100644 src/__stories__/useWindowScroll.story.tsx create mode 100644 src/useWindowScroll.ts diff --git a/docs/useWindowScroll.md b/docs/useWindowScroll.md new file mode 100644 index 0000000000..09d325d097 --- /dev/null +++ b/docs/useWindowScroll.md @@ -0,0 +1,20 @@ +# `useWindowSize` + +React sensor hook that re-renders on window scroll + +## Usage + +```jsx +import {useWindowScroll} from 'react-use'; + +const Demo = () => { + const {x, y} = useWindowScroll(); + + return ( +
+
x: {x}
+
y: {y}
+
+ ); +}; +``` diff --git a/src/__stories__/useWindowScroll.story.tsx b/src/__stories__/useWindowScroll.story.tsx new file mode 100644 index 0000000000..8b84475f1c --- /dev/null +++ b/src/__stories__/useWindowScroll.story.tsx @@ -0,0 +1,30 @@ +import * as React from 'react'; +import {storiesOf} from '@storybook/react'; +import {useWindowScroll} from '..'; +import ShowDocs from '../util/ShowDocs'; + +const Demo = () => { + const {x, y} = useWindowScroll(); + + return ( +
+
+
x: {x}
+
y: {y}
+
+
+ ); +}; + +storiesOf('Sensors/useWindowScroll', module) + .add('Docs', () => ) + .add('Demo', () => + + ) diff --git a/src/index.ts b/src/index.ts index 6fb4a79f76..514af8dbdb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -47,6 +47,7 @@ import useTween from './useTween'; import useUnmount from './useUnmount'; import useUpdate from './useUpdate'; import useVideo from './useVideo'; +import useWindowScroll from './useWindowScroll'; import useWindowSize from './useWindowSize'; import useWait from './useWait'; import useUpdateEffect from './useUpdateEffect' @@ -101,6 +102,7 @@ export { useUnmount, useUpdate, useVideo, + useWindowScroll, useWindowSize, useWait, useUpdateEffect diff --git a/src/useWindowScroll.ts b/src/useWindowScroll.ts new file mode 100644 index 0000000000..4003c7d469 --- /dev/null +++ b/src/useWindowScroll.ts @@ -0,0 +1,39 @@ +import {useState, useEffect, useRef} from 'react'; +import {isClient} from './util'; + +export interface State { + x: number; + y: number; +} + +const useWindowScroll = (): State => { + const frame = useRef(0); + const [state, setState] = useState({ + x: isClient ? window.scrollX : 0, + y: isClient ? window.scrollY : 0 + }) + + useEffect(() => { + const handler = () => { + cancelAnimationFrame(frame.current) + + frame.current = requestAnimationFrame(() => { + setState({ + x: window.scrollX, + y: window.scrollY + }) + }) + } + + window.addEventListener('scroll', handler, { + capture: false, + passive: true + }) + + return () => window.removeEventListener('scroll', handler) + }, []) + + return state +} + +export default useWindowScroll From 2fd08f8335ba998253e7d368a4ab51d77ffa7e40 Mon Sep 17 00:00:00 2001 From: Ward Oosterlijnck Date: Sat, 23 Mar 2019 16:49:22 +1100 Subject: [PATCH 2/2] Added readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8d2f0faab1..569c82e26c 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ - [`useNetwork`](./docs/useNetwork.md) — tracks state of user's internet connection. - [`useOrientation`](./docs/useOrientation.md) — tracks state of device's screen orientation. - [`useSize`](./docs/useSize.md) — tracks some HTML element's dimensions. + - [`useWindowScroll`](./docs/useWindowScroll.md) — tracks `Window` scroll position. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/sensors-usewindowscroll--docs) - [`useWindowSize`](./docs/useWindowSize.md) — tracks `Window` dimensions. [![][img-demo]](https://codesandbox.io/s/m7ln22668)