Reactのfunctionコードでスクロールイベント等を実装すると、
イベント関数をuseCallback
でくくってメモ化しておかないとremoveEventListener
が働かないとか、
スクロールで使用するフラグはuseRef
で再レンダリングされないようにする...など、
意外と気に掛ける点が多かったので、備忘録も込めてコードを載せておきます。
import React, {
useState, useEffect, useRef, useCallback,
} from 'react'
const TestDom = () => {
const [isDisplay, setIsDisplay] = useState(false)
const isRunning = useRef(false) // スクロール多発防止用フラグ
// リスナに登録する関数
const isScrollToggle = useCallback(() => {
if (isRunning.current) return
isRunning.current = true
const scrollTop = window.pageYOffset || document.documentElement.scrollTop
requestAnimationFrame(() => {
if (scrollTop > 100) {
setIsDisplay(true)
} else {
setIsDisplay(false)
}
isRunning.current = false
})
}, [])
// 登録と後始末
useEffect(() => {
document.addEventListener('scroll', isScrollToggle, { passive: true })
return () => {
document.removeEventListener('scroll', isScrollToggle, { passive: true })
}
}, [])
// バツボタンでリスナ削除~ などはこのように
const onClickClose = () => {
document.removeEventListener('scroll', isScrollToggle, { passive: true })
setIsDisplay(false)
}