-
state 변경함수 사용시 주의점 : asyncReact 2022. 3. 24. 19:02
자바스크립트는 코드를 작성하면 일반적으로 synchronous 하게 처리한다고 한다. 번역하면 동기적 이라고 하는데, 쉽게 말하면 위에서부터 순서대로 처리하는 것을 뜻한다.
하지만, 자바스크립트는 이상한 함수들을 사용하면 asynchronous 하게 코드실행이 가능하다. 번역하면 비동기적인데
ajax, 이벤트리스너, setTimeout 이런 함수들을 쓸 때 그런 현상이 일어난다고 한다.
예를 들어, ajax는 컴퓨터가 안좋으면 실행시간이 10초가 걸릴 수 있다. 그래서 이런 함수들로 실행되는 코드는 순차적으로 실행되지 않고, 완료되면 실행된다.
console.log(1+1) axios로 get요청하고나서 console.log(1+2) 실행해주셈~ console.log(1+3)
이런 코드도, 2, 4, 3 순서대로 출력이 된다. ajax.get요청이 0.0000초가 걸려도 물리적으로 처리가 보류되어서 그렇다고 한다.
이제 리액트로 넘어가서
function App(){ let [name, setName] = useState('kim') }
여기서 setName('park')을 사용해 name이란 state를 바꿀 수 있는데, 이런 state변경함수는 전부 asynchronous (비동기적)으로 실행된다. 즉, setName()이 오래걸리면 제쳐놓고 다른 코드부터 실행된다는 뜻이다. 여기서 문제가 생길 수 있다.
예를 들면,
let [count, setCount] = useState(0); let [age, setAge] = useState(20); <button onClick={()=>{ setCount(count+1); if (count < 3) { setAge(age+1) } }} >누르면한살먹기</button>
이런 코드에서, 버튼을 누르면 count가 증가하는데 count가 3보다 작을 때만 age가 1씩 증가해야 한다.
실행해보면, 0 20 -> 1 21 -> 2 22 -> 3 23 -> 4 23 이렇게 count가 3이어도 age가 23까지 간다. 이 현상은 async 때문인데, setCount(count+1)은 오래 걸리니까 먼저, if (count < 3) {}을 실행하는데, 이때 count가 2라서 동작하고 있는 것이다.
이럴땐 useEffect를 활용해 버그를 잡을 수 있다.
하지만 위와 같은 예제는, count와 age를 변수로 잡아도 될 것 같고, 오브젝트형으로 같은 변수에 담아도 될 것 같다.
'React' 카테고리의 다른 글
PWA (0) 2022.03.25 성능잡기 (lazy loading, React devtools, 재렌더링을 막는 memo) (0) 2022.03.25 리액트에서 자주쓰는 if문 작성패턴 5개 (0) 2022.03.24 Redux useSelector과 useDispatch (0) 2022.03.23 Redux dispacth로 수정할 때 데이터보내기 (0) 2022.03.23