자바스크립트는 일반적으로 코드를 작성하면
동기적(synchronous)으로(= 윗줄부터 차례로) 코드가 실행된다.
그러나 특정 코드들은 비동기적(asynchronous)으로 실행되는데
React의 useState가 대표적이다.
function App(){
let [count, setCount] = useState(0);
let [age, setAge] = useState(20);
return (
<div>
<div>안녕하십니까 전 {age}</div>
<button onClick={()=>{
setCount(count + 1);
if (count < 3) {
setAge(age + 1);
}
}}>
누르면 한살먹기
</button>
</div>
)
}
// 출력순서: 21 -> 1 -> 22 -> 2 -> 23 -> 3
if문에서 count가 2일 때까지 실행해주는 것으로 보아
코드를 짠 사람의 의도는
age가 22가 되면 멈추게 하는 것이다.
하지만 실제로는 if문이 setCount보다 동기적으로 먼저 실행되면서
age가 23까지 증가해버린다.
이런 코드를 예측 가능한 순서대로 실행하고 싶으면
useEffect를 활용하면 된다.
useEffect(()=>{
if (count < 3) {
setAge(age + 1)
}
}, [count]);
useEffect에 if문을 넣고 의존성 배열에 count를 추가하여
age를 증가시키는 코드가
count가 바뀔 때만 실행되도록 한다.
<button onClick={()=>{
setCount(count + 1);
}}>
누르면한살먹기
</button>
버튼의 onClick에는 setCount만 넣는다.
버튼을 눌러 count가 증가했을 때만 age가 증가한다.
= 버튼을 2번 누르면 age는 정확하게 + 2
=> 버튼을 누른 횟수만큼만 age가 증가하게 된다.
기존 코드에서는 button을 눌렀을 때
비동기 setter와 동기 if문이 한번에 실행되면서
setter가 더 윗줄에 있어도 항상 if문이 먼저 실행되어버렸다.
하지만 useEffect를 활용하여
'setter가 바뀌었을 때' if문이 실행되게 해주면
언제나 setter가 바뀌고 난 뒤에야 if문이 실행되기 때문에
코드 작성자가 원하는 결과를 얻을 수 있다.
출처: 코딩애플 리액트 강좌