function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
위에 코드에서 어떻게 이펙트가 최신의 count
상태를 읽어 들일까요?
우리는 이미 count
는 특정 컴포넌트 랜더링에 포함되는 상수라고 배웠습니다. 이벤트 핸들러는 그 랜더링에 “속한” count
상태를 “봅니다”. count
는 특정 범위 안에 속하는 변수이기 때문입니다. 이펙트에도 똑같은 개념이 적용됩니다!
“변화하지 않는” 이펙트 안에서 count
변수가 임의로 바뀐다는 뜻이 아닙니다. 이펙트 함수 자체가 매 랜더링마다 별도로 존재합니다.
// 최초 랜더링 시
function Counter() {
// ...
useEffect(
// 첫 번째 랜더링의 이펙트 함수
() => {
document.title = `You clicked ${0} times`;
}
);
// ...
}
// 클릭하면 함수가 다시 호출된다
function Counter() {
// ...
useEffect(
// 두 번째 랜더링의 이펙트 함수
() => {
document.title = `You clicked ${1} times`;
}
);
// ...
}
// 또 한번 클릭하면, 다시 함수가 호출된다
function Counter() {
// ...
useEffect(
// 세 번째 랜더링의 이펙트 함수
() => {
document.title = `You clicked ${2} times`;
}
);
// ..
}
리액트는 여러분이 제공한 이펙트 함수를 기억해 놨다가 DOM의 변화를 처리하고 브라우저가 스크린에 그리고 난 뒤 실행합니다.
따라서 비록 우리가 하나의 개념으로 이펙트를 이야기하고 있지만(도큐먼트의 타이틀을 업데이트 하는 동작), 사실 매 랜더링 마다 다른 함수라는 뜻입니다. 그리고 각각의 이펙트 함수는 그 랜더링에 “속한” props와 state를 “봅니다”.
개념적으로, 이펙트는 랜더링 결과의 일부라 생각할 수 있습니다.
더 자세히 이해할 수 있도록, 다시 생각해 봅시다.
0
일 때의 UI를 보여줘.<p>You clicked 0 times</p>
가 있어.() => { document.title = 'You clicked 0 times' }
.() => { document.title = 'You clicked 0 times' }
를 실행하는 중.그럼 버튼을 클릭하면 어떤 일이 벌어지는지 다시 생각해 봅시다.
1
로 변경해줘.1
일때의 UI를 줘.