import React from 'react' ; import useWindowEvent from './useWindowEvent' ; import { getRectFor } from '../helpers/geometry' ; import { getWindow , isBrowser } from '../helpers/window' ; import { noop } from '../helpers/noop' ; param { Boolean } once example function useInView < T extends HTMLElement > ( { offset = 0 , once = true , } = { } ) { if ( ! isBrowser ( ) ) { return [ noop , false ] ; } const [ node , setNode ] = React . useState ( null ) ; const [ inView , setInView ] = React . useState ( false ) ; const [ scroll , setScroll ] = React . useState ( 0 ) ; const [ rect , setRect ] = React . useState ( { top : 0 , height : 0 } ) ; const environment = getWindow ( ) ; useWindowEvent ( 'scroll' , ( ) => { setScroll ( environment . scrollY ) ; } ) ; React . useEffect ( ( ) => { setRect ( getRectFor ( node ) ) ; } , [ node ] ) ; React . useLayoutEffect ( ( ) => { const { top , height } = rect ; const { innerHeight } = environment ; if ( top ) { if ( scroll >= top + offset - innerHeight ) { setInView ( true ) ; } if ( scroll > top + height || scroll < top - innerHeight ) { if ( ! once ) { setInView ( false ) ; } } } } , [ scroll ] ) ; return [ setNode , inView ] ; } export default useInView ;