현상
• useEffect를 dependency 없이 ([]) 등록해놓고 • 안에서 어떤 이벤트 리스너를 붙임 (예: window.addEventListener, document.addEventListener 등) • 그 이벤트 핸들러 안에서는 React state를 사용하고 싶음 • 문제: 나중에 상태가 바뀌어도, 이벤트 핸들러는 “처음 렌더링 시점”의 값만 계속 참조하고 최신값을 반영하지 않음
방법1
상태를 ref로 관리하기
자세한 설명 ⇒ 왜 ref.current는 항상 새로운 값을 참조할까?
const [count, setCount] = useState(0); const countRef = useRef(count); useEffect(() => { countRef.current = count; }, [count]); // count가 바뀔 때마다 ref 업데이트 useEffect(() => { const handler = () => { console.log('최신 count:', countRef.current); }; window.addEventListener('click', handler); return () => window.removeEventListener('click', handler); }, []);
방법2
useEffect의 dependency array에 상태를 넣어, 이벤트 핸들러 자체를 매번 새로 등록
useEffect(() => { const handler = () => { console.log('최신 count:', count); }; window.addEventListener('click', handler); return () => window.removeEventListener('click', handler); }, [count]); // count가 바뀔 때마다 이벤트 다시 등록
비교하기
방법1) 이벤트 리스너가 한번만 등록되어 퍼포먼스가 좋음
방법2) ref 필요없이 dependency만 추가하면 되어 간편. but 상태가 바뀔 때마다 리스너 등록/해제 비용 발생
- “많은 상태 변화가 자주 일어나고”, “핸들러 등록/해제 비용이 크다면” → ref 추천
- “변화가 적거나 단순한 경우” → 핸들러 재등록도 충분히 OK
웬만해선 방법1이 더 좋을 듯 하다!!