@@ -2,30 +2,61 @@ import { useState } from 'react'
22
33import useStableMemo from './useStableMemo'
44import useEffect from './useIsomorphicEffect'
5+ import useEventCallback from './useEventCallback'
56
67/**
78 * Setup an [`IntersectionObserver`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver) on
8- * a DOM Element.
9+ * a DOM Element that returns it's entries as they arrive .
910 *
1011 * @param element The DOM element to observe
1112 * @param init IntersectionObserver options
1213 */
13- export default function useIntersectionObserver < TElement extends Element > (
14+ function useIntersectionObserver < TElement extends Element > (
1415 element : TElement | null | undefined ,
15- { threshold, root, rootMargin } : IntersectionObserverInit = { } ,
16- ) {
16+ options : IntersectionObserverInit ,
17+ ) : IntersectionObserverEntry [ ]
18+ /**
19+ * Setup an [`IntersectionObserver`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver) on
20+ * a DOM Element. This overload does not trigger component updates when receiving new
21+ * entries. This allows for finer grained performance optimizations by the consumer.
22+ *
23+ * @param element The DOM element to observe
24+ * @param callback A listener for intersection updates.
25+ * @param init IntersectionObserver options
26+ */
27+ function useIntersectionObserver < TElement extends Element > (
28+ element : TElement | null | undefined ,
29+ callback : IntersectionObserverCallback ,
30+ options : IntersectionObserverInit ,
31+ ) : void
32+ function useIntersectionObserver < TElement extends Element > (
33+ element : TElement | null | undefined ,
34+ callbackOrOptions : IntersectionObserverCallback | IntersectionObserverInit ,
35+ maybeOptions ?: IntersectionObserverInit ,
36+ ) : void | IntersectionObserverEntry [ ] {
37+ let callback : IntersectionObserverCallback | undefined
38+ let options : IntersectionObserverInit
39+ if ( typeof callbackOrOptions === 'function' ) {
40+ callback = callbackOrOptions
41+ options = maybeOptions || { }
42+ } else {
43+ options = callbackOrOptions || { }
44+ }
45+ const { threshold, root, rootMargin } = options
1746 const [ entries , setEntry ] = useState < IntersectionObserverEntry [ ] | null > ( null )
1847
48+ const handler = useEventCallback ( callback || setEntry )
49+
1950 const observer = useStableMemo (
2051 ( ) =>
2152 typeof IntersectionObserver !== 'undefined' &&
22- new IntersectionObserver ( entries => setEntry ( entries ) , {
53+ new IntersectionObserver ( handler , {
2354 threshold,
2455 root,
2556 rootMargin,
2657 } ) ,
2758
28- [ root , rootMargin , threshold && JSON . stringify ( threshold ) ] ,
59+ [ handler , root , rootMargin , threshold && JSON . stringify ( threshold ) ] ,
2960 )
3061
3162 useEffect ( ( ) => {
@@ -38,5 +69,7 @@ export default function useIntersectionObserver<TElement extends Element>(
3869 }
3970 } , [ observer , element ] )
4071
41- return entries || [ ]
72+ return callback ? undefined : entries || [ ]
4273}
74+
75+ export default useIntersectionObserver
0 commit comments