Framework/React

[React] window scroll event handler ์ด๋ฒคํŠธ๊ฐ€ ์•ˆ๋จนํž ๋•Œ, scrollY always 0

yuri lee 2024. 5. 25. 15:20
๋ฐ˜์‘ํ˜•

Intro

์•ˆ๋…•ํ•˜์„ธ์š”. React์—์„œ window.scroll ์ด๋ฒคํŠธ๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์•„๋ฌด๋ฆฌ window.scrollY ๊ฐ’์„ ๊ตฌํ•ด๋„ 0์œผ๋กœ ๋‚˜์˜ค๋”๋ผ๊ณ ์š”. 

 

 

์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. 

// state
const [scrollTop, setScrollTop] = useState(0),
    headerRef = useRef<HTMLDivElement>(null),
    headerHeight = headerRef?.current?.clientHeight ?? 0,
    
// useEffect
useEffect(() => {
    const handleScroll = () => {
        setScrollTop(window.scrollY);
    };
    handleScroll();
    window.addEventListener('scroll', handleScroll);
    return () => {
        window.removeEventListener('scroll', handleScroll);
    };
}, []);

// rendering
<section style={{right: handlePositionState}} ref={bottomSheetRef}>
    <div className={scrollTop > headerHeight ? `${styles.tabArea} ${styles.active}` : styles.tabArea}>
       ....
    </div>
</section>

 

ํŠน์ • ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํŒ์—… ๋œจ๋Š” ํ˜•ํƒœ์˜€์Šต๋‹ˆ๋‹ค. ๋ถ€๋ชจ component์—๋„ scroll์ด ์žˆ๊ณ , ํŒ์—… ์ปดํฌ๋„ŒํŠธ์—๋„ scroll์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ํŒ์—… ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—ด๋ฆฌ๋Š” ์ˆœ๊ฐ„ ํŒ์—… ์ปดํฌ๋„ŒํŠธ์— ๋ถ€๋ชจ์˜ ์Šคํฌ๋กค์˜ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๊ธฐ ์œ„ํ•ด body์— overflow: hidden; height: 100vh; ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์–ด์š”.

 

์ดํ›„ ํŒ์—… ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ ํŠน์ • ์Šคํฌ๋กค ์œ„์น˜์— ๋„๋‹ฌํ•˜๋ฉด css ํšจ๊ณผ๋ฅผ ์ฃผ๊ธฐ ์œ„ํ•ด window.scrollY๊ฐ’์ด ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ window.scrollY ์ด ๊ณ„์† 0์œผ๋กœ ๋‚˜์˜ค๋”๋ผ๊ณ ์š”.

 

Why? 

๊ตฌ๊ธ€๋ง ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ body์— overflow:hidden ์„ ์‚ญ์ œํ•˜๋ฉด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•œ๋‹ค๋Š” ๋‚ด์šฉ์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ œ ์ผ€์ด์Šค์˜ ๊ฒฝ์šฐ hidden์„ ์‚ญ์ œํ•˜๋ฉด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ ์Šคํฌ๋กค์ด ๋ณด์—ฌ์ง€๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋Ÿด ์ˆœ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ์™ธ์—๋„ scrollHeight, clientHeight ๋“ฑ ๋‹ค๋ฅธ ์†์„ฑ๋„ ์‚ฌ์šฉํ•ด๋ดค์ง€๋งŒ ๊ฒฐ๊ณผ๋Š” ๋˜‘๊ฐ™์•˜์Šต๋‹ˆ๋‹ค. 

 

How to solve problem

window ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ useRef๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์ตœ์ƒ์œ„ ๋†’์ด๋ฅผ ๊ตฌํ•˜์—ฌ ์•„๋ž˜์™€ ๊ฐ™์ด ํ™œ์šฉํ•˜๋‹ˆ scroll handler๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์˜€์Šต๋‹ˆ๋‹ค. 

const bottomSheetRef = useRef<HTMLDivElement>(null)

useEffect(() => {
    const handleScroll = () => {
        setScrollTop(bottomSheetRef?.current?.scrollTop ?? 0);
    };

    handleScroll();
    bottomSheetRef?.current?.addEventListener('scroll', handleScroll);
    return () => {
        bottomSheetRef?.current?.removeEventListener('scroll', handleScroll);
    };
}, []);

 

ํ˜น์‹œ React์—์„œ ์ €์™€ ๊ฐ™์€ ์ƒํ™ฉ์ด์‹  ๋ถ„๋“ค์ด ๊ณ„์‹œ๋‹ค๋ฉด ์œ„ ๋ฐฉ๋ฒ•์„ ํ•œ๋ฒˆ ํ™œ์šฉํ•ด๋ณด์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค :) 

๋ฐ˜์‘ํ˜•