React에서 스크롤 이벤트를 처리하는 방법은 무엇인가요?
_____A1: React에서는 `window` 또는 특정 요소에 `scroll` 이벤트 리스너를 추가하여 스크롤 이벤트를 감지할 수 있습니다. 보통 `useEffect` 훅 내에서 `window.addEventListener('scroll', handler)`를 사용하고, 컴포넌트 언마운트 시 `removeEventListener`로 정리합니다.
---
Q2: 예시 코드를 보여주세요.
A2: 기본적인 예시는 다음과 같습니다.
```jsx
import React, { useEffect, useState } from 'react';
function ScrollComponent() {
const [scrollY, setScrollY] = useState(0);
useEffect(() => {
const handleScroll = () => {
setScrollY(window.scrollY);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
return
현재 스크롤 위치: {scrollY}px
;}
```
---
Q3: 특정 스크롤 컨테이너 요소에 스크롤 이벤트를 듣고 싶으면?
A3: `window` 대신 해당 컨테이너의 `ref`를 사용하여 다음과 같이 이벤트를 등록할 수 있습니다.
```jsx
import React, { useRef, useEffect, useState } from 'react';
function ScrollContainer() {
const containerRef = useRef(null);
const [scrollTop, setScrollTop] = useState(0);
useEffect(() => {
const container = containerRef.current;
if (!container) return;
const onScroll = () => {
setScrollTop(container.scrollTop);
};
container.addEventListener('scroll', onScroll);
return () => container.removeEventListener('scroll', onScroll);
}, []);
return (
ref={containerRef}
style={{ overflowY: 'scroll', height: '200px', border: '1px solid black' }}
>
{/* 내용 */}
스크롤 위치: {scrollTop}px
);
}
```
---
Q4: 스크롤 이벤트 핸들러에서 성능 최적화 방법은?
A4: 스크롤 이벤트는 고빈도로 발생하므로, `throttle` 또는 `debounce` 기법을 사용하여 이벤트 호출 횟수를 제한하는 것이 좋습니다. lodash의 `throttle` 함수를 사용하거나 임의로 구현할 수 있습니다.
예:
```jsx
import { throttle } from 'lodash';
useEffect(() => {
const handleScroll = throttle(() => {
// 핸들링 로직
}, 200);
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
```
---
Q5: React에서 스크롤 위치에 따라 특정 동작을 트리거하려면?
A5: 스크롤 위치 상태를 저장한 후 조건문으로 원하는 시점에 동작을 실행합니다. 예를 들어 특정 위치 이상일 때 헤더를 변경하거나, 무한 스크롤에서 데이터를 추가 요청하는 방식입니다.
---
Q6: 이벤트 등록을 컴포넌트에 직접 넣지 않고 쉽게 관리하는 방법은?
A6: 커스텀 훅으로 분리하면 재사용과 관리가 용이합니다.
예:
```jsx
import { useState, useEffect } from 'react';
function useScrollPosition() {
const [scrollPos, setScrollPos] = useState(0);
useEffect(() => {
const onScroll = () => {
setScrollPos(window.scrollY);
};
window.addEventListener('scroll', onScroll);
return () => window.removeEventListener('scroll', onScroll);
}, []);
return scrollPos;
}
```
---
Q7: React 18 이상에서 비동기성과 스크롤 이벤트는 어떻게 관련되나요?
A7: React 18부터 Strict Mode에서 일부 훅이 두 번 호출될 수 있으므로, 이벤트 등록과 해제 로직을 정확히 구현하여 메모리 누수나 중복 등록 문제가 없도록 주의해야 합니다.
---
요약:
1. `useEffect` 내에서 스크롤 이벤트 리스너를 추가 및 제거한다.
2. 성능 최적화를 위해 `throttle`/`debounce`를 활용한다.
3. `ref`를 통해 특정 요소에만 이벤트 적용이 가능하다.
4. 커스텀 훅으로 재사용성 및 관리성을 높인다.
5. React 최신 버전과 Strict Mode 특성에 주의한다.
아래에서는 React에서 스크롤 이벤트를 처리하는 방법에 대해 자세히 설명하겠습니다.
1. 기본적인 스크롤 이벤트 처리 React에서 스크롤 이벤트를 처리하기 위해서는 `useEffect` 훅을 사용하여 컴포넌트가 마운트될 때 이벤트 리스너를 추가하고, 언마운트될 때 이를 정리하는 방식으로 진행합니다.
```jsx import React, { useEffect, useState } from 'react'; const ScrollComponent = () => { const [scrollY, setScrollY] = useState(0); const handleScroll = () => { setScrollY(window.scrollY); }; useEffect(() => { window.addEventListener('scroll', handleScroll); // Cleanup function to remove the event listener return () => { window.removeEventListener('scroll', handleScroll); }; }, []); return (
Scroll Position: {scrollY}px
{/* 긴 내용을 추가하여 스크롤을 가능하게 합니다.*/}
2. 특정 요소에 대한 스크롤 이벤트 처리 특정 DOM 요소에 대한 스크롤 이벤트를 처리하고 싶다면, 해당 요소에 대한 참조를 생성하고, 그 요소에 이벤트 리스너를 추가하면 됩니다.
```jsx import React, { useEffect, useRef, useState } from 'react'; const ScrollableComponent = () => { const scrollRef = useRef(null); const [scrollTop, setScrollTop] = useState(0); const handleScroll = () => { if (scrollRef.current) { setScrollTop(scrollRef.current.scrollTop); } }; useEffect(() => { const scrollElement = scrollRef.current; if (scrollElement) { scrollElement.addEventListener('scroll', handleScroll); // Cleanup function return () => { scrollElement.removeEventListener('scroll', handleScroll); }; } }, []); return (
Scroll Position: {scrollTop}px
Scroll me!
3. 성능 최적화 스크롤 이벤트는 매우 자주 발생할 수 있기 때문에, 성능을 최적화하는 것이 중요합니다.
이를 위해 `debounce` 또는 `throttle` 기법을 사용할 수 있습니다.
Lodash와 같은 라이브러리를 사용하면 쉽게 구현할 수 있습니다.
```jsx import React, { useEffect, useState } from 'react'; import { debounce } from 'lodash'; const DebouncedScrollComponent = () => { const [scrollY, setScrollY] = useState(0); const handleScroll = debounce(() => { setScrollY(window.scrollY); }, 100); // 100ms 간격으로 호출 useEffect(() => { window.addEventListener('scroll', handleScroll); return () => { window.removeEventListener('scroll', handleScroll); }; }, []); return (
Scroll Position: {scrollY}px
4. 스크롤 위치 저장 애플리케이션에서 스크롤 위치를 저장하고 복원하는 기능이 필요할 수 있습니다.
이 경우, `localStorage`를 사용하여 스크롤 위치를 저장하고, 컴포넌트가 마운트될 때 해당 위치로 스크롤을 이동할 수 있습니다.
```jsx import React, { useEffect, useState } from 'react'; const ScrollPositionComponent = () => { const [scrollY, setScrollY] = useState(0); const handleScroll = () => { setScrollY(window.scrollY); localStorage.setItem('scrollPosition', window.scrollY); }; useEffect(() => { const savedScrollY = localStorage.getItem('scrollPosition'); if (savedScrollY) { window.scrollTo(0, parseInt(savedScrollY,
10)); } window.addEventListener('scroll', handleScroll); return () => { window.removeEventListener('scroll', handleScroll); }; }, []); return (
Scroll Position: {scrollY}px
이러한 방법들을 적절히 조합하여 사용자 경험을 향상시키는 것이 중요합니다.