배경색 상태관리 (useState): 지금 현재 배경색을 기억하고, 그 색을 바꿀 수 있는 setBgColor를 만든다. 초기값은 #111827로 설정한다.
const [bgColor, setBgColor] = useState('#111827');
각 섹션별 useRef 7개: 'Home', 'About' 등 7개 섹션에 각각 붙여줄 빈 이름표(ref)를 만든다. 이 이름표의 .current 속성은 null이다.
const sectionRefs = {
home: useRef<HTMLElement>(null),
about: useRef<HTMLElement>(null),
// ... (총 7개)
};
<HTMLElement>: "그리고 이 상자의 .current 에는, 나중에 HTMLElement 타입의 객체만 담을 거야!"
page.tsx의 return 문 안에서, 7개의 섹션 컴포넌트를 호출하며, 1에서 준비한 '이름표'(ref)를 각자에게 나눠준다.
ref를 받아서, 자신이 그리는 실제 <section> HTML 태그에 ref={ref} 코드로 부착한다.<section> 태그에 data-color="#111827" 속성을 추가한다.
page.tsx가 처음 렌더링을 마친 직후, useEffect(..., []) ('딱 한 번만 실행')가 실행된다.
new IntersectionObserver)를 만든다.isIntersecting), 그 녀석의 data-color 값을 읽어서 setBgColor로 state 값을 설정한다.sectionRefs 7개를 모두 뒤져서, .current에 실제 태그가 채워진 것들을 찾아낸다.observe 감시하라고 명령한다.// 콜백 함수 시작: 스크롤 센서가 감지한 항목들의 배열(entries)을 받는다.
(entries) => {
// 발견된 항목들(entries)을 하나씩 순회한다.
entries.forEach((entry) => {
// 화면에 들어왔는지(Intersecting) 확인한다
if (entry.isIntersecting) {
// 실제 HTML 태그(target)에서 'data-color' 속성값을 읽어온다.
const color = entry.target.getAttribute("data-color");
// 만약 유효한 색상값(color)이 존재하면
if (color) {
// page.tsx의 상태(State)를 변경하여 리렌더링을 유발한다.
setBgColor(color);
}
}
});
},
// 센서 민감도 설정 50%가 보여야 작동한다.
{ threshold: 0.5 }
// 이름표 상자들만 모두 배열로 추출한다.
const refs = Object.values(sectionRefs);
// 추출된 이름표 상자들(ref)을 하나씩 확인한다.
refs.forEach((ref) => {
// 만약 이 이름표 상자 안에 실제 HTML 태그가 채워져 있다면
if (ref.current) {
// 스크롤 센서(observer)에게 이 실제 태그를 감시하기 시작하라고 한다.
observer.observe(ref.current);
}
});
// sectionRefs의 모양 (객체)
{
home: { current: <section id="home"> },
about: { current: <section id="about"> },
// ...
}
// refs의 모양 (배열)
[
{ current: <section id="home"> },
{ current: <section id="about"> },
// ...
]

전체 흐름의 완성:
1. 사용자가 스크롤한다.
2. About 섹션이 50% 보인다.
3. 스크롤 센서(Observer)가 감지하고 setBgColor("#1f2937")를 호출한다.
4. page.tsx가 리렌더링된다. (bgColor의 '현재 값'이 #1f2937로 바뀐다.)
5. 리렌더링이 끝난 직후, 배경색 변경 useEffect 함수(useEffect(..., [bgColor]))가 실행된다.
6. document.body.style.backgroundColor = "#1f2937"이 실행된다.
7. 결과: 사용자는 배경색이 바뀌는 것을 본다.
