Type checking + minor improvements useScroll

This commit is contained in:
Ward Oosterlijnck 2019-04-06 15:31:48 +11:00
parent eab6c51ddf
commit 5b39ab5d24
3 changed files with 34 additions and 22 deletions

View File

@ -1,6 +1,6 @@
# `useScroll`
React sensor hook that re-renders on when scroll position in a DOM element changes.
React sensor hook that re-renders when the scroll position in a DOM element changes.
## Usage
@ -8,14 +8,20 @@ React sensor hook that re-renders on when scroll position in a DOM element chang
import {useScroll} from 'react-use';
const Demo = () => {
const element = React.useRef(null);
const {x, y} = useScroll(element);
const scrollRef = React.useRef(null);
const {x, y} = useScroll(scrollRef);
return (
<div ref={element}>
<div ref={scrollRef}>
<div>x: {x}</div>
<div>y: {y}</div>
</div>
);
};
```
## Reference
```ts
useScroll(ref: RefObject<HTMLElement>);
```

View File

@ -4,15 +4,15 @@ import {useScroll} from '..';
import ShowDocs from './util/ShowDocs';
const Demo = () => {
const element = React.useRef(null);
const {x, y} = useScroll(element);
const scrollRef = React.useRef(null);
const {x, y} = useScroll(scrollRef);
return (
<>
<div>x: {x}</div>
<div>y: {y}</div>
<div
ref={element}
ref={scrollRef}
style={{
width: '400px',
height: '400px',
@ -30,6 +30,4 @@ const Demo = () => {
storiesOf('Sensors/useScroll', module)
.add('Docs', () => <ShowDocs md={require('../../docs/useScroll.md')} />)
.add('Demo', () =>
<Demo/>
)
.add('Demo', () => <Demo/>)

View File

@ -1,30 +1,38 @@
import {useState, useEffect, useRef} from 'react';
import {isClient} from './util';
import {useState, useEffect, useRef, RefObject} from 'react';
export interface State {
x: number;
y: number;
}
const useScroll = (ref): State => {
const useScroll = (ref: RefObject<HTMLElement>): State => {
if (process.env.NODE_ENV === 'development') {
if ((typeof ref !== 'object') || (typeof ref.current === 'undefined')) {
console.error('`useScroll` expects a single ref argument.');
}
}
const frame = useRef(0);
const [state, setState] = useState<State>({
x: isClient ? window.scrollX : 0,
y: isClient ? window.scrollY : 0
x: 0,
y: 0
});
useEffect(() => {
const handler = () => {
cancelAnimationFrame(frame.current)
frame.current = requestAnimationFrame(() => {
setState({
x: ref.current.scrollLeft,
y: ref.current.scrollTop
});
if (ref.current) {
setState({
x: ref.current.scrollLeft,
y: ref.current.scrollTop
})
}
});
}
if (ref && ref.current) {
if (ref.current) {
ref.current.addEventListener('scroll', handler, {
capture: false,
passive: true
@ -36,11 +44,11 @@ const useScroll = (ref): State => {
cancelAnimationFrame(frame.current);
}
if (ref && ref.current) {
if (ref.current) {
ref.current.removeEventListener('scroll', handler);
}
};
}, [ref]);
}, [ref.current]);
return state;
}