우연히 글을 보다가 useState()가 비동기방식이라는 것을 알 수 있었다. 근데 react 코드를 짜면서 느낄 수 있는 부분들이 많아 놀랍지는 않았지만, 개념으로 확인시켜주니 좋았다. 그래서 비동기방식으로 처리할 때 불편함이 있어 동기 방식으로 처리하는 방식을 알고자 정리하게 되었다.
개념
const로 선언하는 이유는?
- 변수의 재할당을 막기 위해서
- let을 사용하면 변수의 재선언이 가능해지기 때문에, 이를 방지하고 setState를 사용한 변수 변경만을 허락하기 위해서 const로 선언
state를 사용하는 이유
변수는 변경되어도 자동으로 화면이 바뀌지 않는다. setState를 사용시 state가 변경되면 자동으로 화면이 바뀌기 때문에 state를 사용한다.
비동기 방식
우선 개념에 대해서 보면, 동기 방식은 동시에 발생하여 요청을 받으면 응답을 받아야 다음 동작이 수행된다. 반면 비동기 방식은 종료여부에 상관없이 다음 작업을 실행한다.
state는 값이 변경되면 리렌더링이 발생하는데, 변경되는 state가 많을수록 리렌더링이 계속 일어나고 속도도 저하되는 등의 성능적으로 문제가 생길 것이다.
그래서 리액트는 성능의 향상을 위해서 setState를 연속 호출하면 배치 처리하여 한 번에 렌더링하도록 하였다. 아무리 많은 setState가 연속적으로 사용되었어도 배치 처리에 의해서 한 번의 렌더링으로 최신 상태를 유지하는 것이다.
여기서 배치란 React가 너 나은 성능을 위해 여러개의 state 업데이트를 하나의 리렌더링으로 묶는 것을 의미한다. 그래서 16ms 동안 변경된 상태 값들을 모아서 한 번에 리렌더링을 진행하는데 이를 batch(일괄) update라고 한다.
동기적으로 처리하기
클래스형은 함수로 처리
const plusNum = () => {
setCnt(cnt+1);
}
→ 여기서도 나눌 수 있다.
setState(updateState)
setState((prevState) => {
return updateState
})
아래 방법을 사용하면 이전 state 객체를 인자로 받고 새로운 state 객체를 반환하는 함수를 받을 수도 있다. 그래서 최신값의 state를 보장받을 수 있기 때문에 setState의 동기적 처리가 가능해진다.
함수형은 useEffect() 사용
updateState = () => {
this.setState(
{ cnt: this.state.cnt + 1 },
()=>{ console.log(this.state.cnt) }
)
}
useEffect(()=>{
console.log(cnt);
},[cnt])