왜 만들었나
포트폴리오 메인의 통계 섹션처럼, 사용자가 직접 보는 순간에만 숫자가 자라나는 효과가 필요했습니다. 라이브러리 없이 IntersectionObserver와 requestAnimationFrame만으로 충분히 만들 수 있어서 작은 훅 하나로 정리했습니다.
핵심 동작
ref가 viewport에 진입하면 IntersectionObserver가 한 번만 트리거
RAF 루프에서 elapsed 비율을 cubic ease-out으로 보간 setState로 React에 반영
도달 후 unobserve로 자기 자신을 떼어 추가 비용 0
언제 좋은가
사용자가 보지 않는 카운팅을 미리 진행하지 않음 절약과 의도가 모두 잡힘
cubic ease-out으로 마지막이 부드럽게 감속되어 자연스러움
한 번 트리거 후 unobserve라 메모리CPU 낭비 없음
언제 별로인가
기본은 1회 실행 반복 트리거가 필요하면 startedRef를 cleanup에서 초기화하거나 옵션을 추가해야 함
viewport 안에서 mount되는 hero 영역이라면 즉시 시작되어 의도와 다를 수 있음 (delay 옵션 추가 가능)
의존성
React 18+, 브라우저 IntersectionObserver. 그 외 라이브러리 없음.