Skip to content

Commit 180b072

Browse files
committed
Improve useNearScreen implementation
1 parent e18e1c2 commit 180b072

File tree

1 file changed

+38
-18
lines changed

1 file changed

+38
-18
lines changed

strategies/useNearScreen.js

+38-18
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,47 @@
11
import {useState, useEffect} from 'react'
22

3+
const targetCallbacks = new WeakMap()
4+
const observerP =
5+
typeof window !== 'undefined' &&
6+
Promise.resolve(
7+
typeof window.IntersectionObserver === 'undefined' &&
8+
import('intersection-observer')
9+
).then(
10+
() =>
11+
new window.IntersectionObserver(entries => {
12+
entries
13+
.filter(e => e.isIntersecting)
14+
.map(e => targetCallbacks.get(e.target))
15+
.filter(Boolean)
16+
.forEach(cb => cb())
17+
})
18+
)
19+
20+
function whenIntersecting(target, cb) {
21+
function unsubscribe() {
22+
observerP.then(observer => {
23+
observer.unobserve()
24+
targetCallbacks.delete(target)
25+
})
26+
}
27+
28+
observerP.then(observer => {
29+
observer.observe(target)
30+
targetCallbacks.set(target, () => {
31+
unsubscribe()
32+
cb()
33+
})
34+
})
35+
36+
return unsubscribe
37+
}
38+
339
export const useNearScreen = ({ref}) => {
440
const [show, setShow] = useState(false)
541

642
useEffect(
7-
function() {
8-
if (!ref || !ref.current) return
9-
10-
Promise.resolve(
11-
typeof window.IntersectionObserver !== 'undefined'
12-
? window.IntersectionObserver
13-
: import('intersection-observer')
14-
).then(() => {
15-
const observer = new window.IntersectionObserver(function(entries) {
16-
const {isIntersecting} = entries[0]
17-
if (isIntersecting) {
18-
setShow(true)
19-
observer.disconnect()
20-
}
21-
})
22-
observer.observe(ref.current)
23-
})
24-
},
43+
() =>
44+
ref && ref.current && whenIntersecting(ref.current, () => setShow(true)),
2545
[ref]
2646
)
2747

0 commit comments

Comments
 (0)