Written by
Parkdev
on
on
[React]JS의 Sync/Async
JS는 기본적으로 synchronous하게 실행된다.
- ‘동기방식’이라는 뜻으로 쉽게 설명하면 위에서부터 순차적으로 실행된다는 뜻이다.
하지만 비동기적으로 작동되는 함수들도 존재한다.
-
주로 시간이 걸리는 함수들이 비동기적(Async)으로 작동하며 대표적인 함수는 다음과 같다.
ajax, Event LIstener, setTimeout 등
-
이러한 함수들은 순서에 상관없이 완료되는 대로 작업이 실행된다.
console.log(1+1)
axios.get ( {호출 함수} )
console.log(1+2)
// 위 코드를 실행하면 2,3이 먼저 출력되고 axios 결과값이 출력된다.
- 특히 axois가 얼마나 걸리든 상관없이 무조건 나중에 실행된다.
이러한 특징으로 인해 async함수를 사용할때, 의도치 않은 버그를 유발 할 수 있다.
- 예제를 하나 풀어보자. 다음과 같은 앱이 하나 있을때 기능을 추가해보자.
function App(){
let [count, setCount] = useState(0);
let [age, setAge] = useState(20);
return (
<div>
<div>안녕하십니까 전 {age}살 입니다.</div>
<button>누르면한살먹기</button>
</div>
)
버튼을 누를 때마다
(1) count라는 state를 +1
(2) age라는 state도 +1
(3) 근데 count 가 3 이상이면 age를 더하지 않도록 제한
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>
)
- 이렇게 작성한다면 기본적으로 Age가 22까지 증가하고 그 이상으로는 증가하지 않기를 생각하지만
- 결과적으로 Age가 23에서 증가 하지 않는다.
이는 set함수가 Async함수이기 때문이다.
- 때문에 위와 같은 코드를 작성한다면, 아래와 같이 작동함을 알 수 있다.
조건문을 먼저 실행 (통과) > setcount, setAge 함수 실행(조건문을 통과했으므로)
이를 해결하는 방법으로는 useEffect가 있다.
function App(){
let [count, setCount] = useState(0);
let [age, setAge] = useState(20);
useEffect(()=> {
if( count>0 && count<3){ // 첫랜더링 실행 방지를 위해 count>0 조건을 추가했다.
setAge(age+1)
}
},[count])
return (
<div>
<div>안녕하십니까 전 {age}살 입니다.</div>
<button onClick={()=>{
setCount(count+1)
}>누르면한살먹기</button>
</div>
)