Hyeon_E 2023. 3. 30. 23:55

sync / async 관련 상식

 

JS는 synchronous(동기방식)하게, 즉 순서대로 코드가 실행

문제는 JS는 몇몇 함수(ajax, 이벤트리스너, setTimeout 등)를 사용하면 asynchronous(비동기적)하게 코드가 실행됨

이런 함수들은 처리시간이 오래걸리기 때문에 코드들이 순차적으로 실행되지 않고 완료되면 실행됨

ajax등의 요청이 0.00초가 걸려도 물리적으로 처리가 보류되어 나중에 실행되는것

 

리액트의 setState 함수에 주의해야 하는 점

function App(){
  let [name, setName] = useState('Lee')
}

setName() 같은 state 변경함수들은 전부 asynchronous (비동기적)으로 처리됨

state 변경함수가 오래 걸리면 다른 밑에 있는 코드부터 실행하는 것

 

여기 버튼을 누르면 2개 기능을 순차적으로 실행하는 예제가 있음

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>
  )

}

버튼을 누를 때마다

  1. count라는 state를 +1, 버튼누른 횟수 기록용
  2. age라는 state를 +1
  3. count가 3 이상일 경우 더 이상 age라는 state를 +1 하지 않음

실제 실행을 해보면 23까지 증가함

이유는 비동기적으로 처리되었기 때문

state 변경함수는 비동기적으로 처리되는 함수기 때문에 완료되기까지 시간이 오래걸리면 다음 코드를 실행해줌

 

그래서 코드를 따라가며 생각해보면

버튼을 눌렀을때 state 변경함수로 22에서 23으로 변경되는것은 시간이 걸리니 놔두고

다음코드인 if문 비교를 할때 count가 2므로 true가 되어 setAge(age+1)을 실행시키는것

 

그래서 예시처럼 state1 변경하고나서 state2를 변경하는 코드를 작성할 땐 문제가 생김

이것을 동기스럽게, 순차적으로 실행하고 싶을 때 해결책은 useEffect

useEffect를 사용하면 특정 state가 변경될 때 useEffect를실행되므로 동기스럽게 바꿀 수 있음

 

function App(){
  let [count, setCount] = useState(0);
  let [age, setAge] = useState(20);
  
  useEffect(()=>{
  if ( count != 0 && count < 3 ) {
    setAge(age+1)
  }
 }, [count]) 

  return (
    <div>
      <div>{age}살</div>
      <button onClick={()=>{
      setCount(count+1);}}>
      누르면한살먹기</button> 
    </div>
  )

}

useEffect는 컴포넌트가 렌더링/재렌더링될 때 실행되는 함수

[ ] 대괄호안에 state를 집어넣으면 state가 변경되면 이 코드 실행해 달라는뜻으로도 사용가능함

  1. count라는 state가 변경되고 나서
  2. age라는 state를 변경해 주세요

이런 식으로 순차적으로 코드를 실행할 수 있는 것

 

위에서는 [ ]대괄호 안에 count를 넣어서 count라는 state가 변경되고 나서 실행이 되며

if문으로 count라는 값을 제대로 측정해 볼 수 있음

 

count != 0을 한 이유는 useEffect 저렇게 써도

처음 페이지 로드될 때도 한번 실행이 되기 때문에 의도치 않은 버그가 발생할 수 있음

그렇기에 count가 0일 때(페이지 처음 로드되었을 때는) 내부 코드를 동작시키지 않도록 하는 것