본 포스팅은 코딩애플님의 리팩트 강의를 수강한 후 참고하여 작성하였습니다.
자바스크립트는 기본적으로 synchronous 하게 처리
그러나 ajax, setTimeout 등 시간이 오래 걸릴 수 있는 함수들에 대해서는 asynchronous 하게 처리
리액트의 setState함수는 asynchronous으로 처리가 됨
이로인해 문제가 발생할 수 있다!
let [count, setCount] = useState(0);
let [age, setAge] = useState(20);
return (
<div className="App">
{count}
<div>안녕하십니까 전 {age}</div>
<button onClick = {() => {
setCount(count+1)
if(count < 3) {
setAge(age+1)
}
}}>누르면 한실먹기</button>
</div>
);
count가 1일 때 age +1
count가 2일 때 age +1
count가 3이면 조건문을 실행하지 않게끔 하였지만
실제로는 3일때도 if분기가 실행된다.
상태를 변경하는 코드가 실행되기 전에
if(count < 3)이라는 코드가 먼저 실행 되기 때문에 발생하는 문제이다.
let [count, setCount] = useState(0);
let [age, setAge] = useState(20);
const isInitialRender = useRef(true);
useEffect(() => {
if(isInitialRender.current) {
isInitialRender.current = false
return
}
if (count < 3) {
setAge(age+1)
}
},[count])
return (
<div className="App">
{count}
<div>안녕하십니까 전 {age}</div>
<button onClick = {() => {
setCount(count+1)
}}>누르면 한실먹기</button>
</div>
);
버튼을 눌렀을 떄 state를 변경하게 하고
state가 변경되었을 때 useEffect 를 이용하여 age가 변경하게끔 작성하여 해당 문제를 막을 수 있었다.
야근하면서 피곤한 상태로 개발하다보면 자주 발생할 수 있는 실수일 것 같다.
state를 변경하는 코드는 항상 조금 더 신중하게 다루자