이미 여럿 살펴보았기에 알만한 내용이지만 React에서의 state는 매우 중요한 개념이다.
state라는 것은 component를 다시 렌더링하고 화면에 표시되는 것을 바꾼다.
이번에 다룰 것은 React가 어떻게 state를 업데이트하는지에 대해 알아보고자 한다.
Scheduled State
이제껏 배운 내용은 component 안에 useState()
hook을 이용해 일부 상태들을 관리할 수 있었다.
'DVD'
값을 가진 product라는 state를 DVD에서 Book으로 state를 변경한다고 해보자.
그동안 살펴보면서 setNewProduct('Book') ;
과 같이 업데이트 함수를 통해 state를 갱신했었다.
여기서 살펴봐야하는 부분은 setNewProduct('Book') ;
이 실행되어 state가 변하지만 바로 변경되지 않는다는 것이다.
대신에 state 업데이트 함수가 호출되면 'Book'
으로 업데이트하게끔 예약을 한다. 이 과정을 scheduled state이라 부른다.
React는 이를 인지하고 처리할 계획을 준비하지만 즉시 처리하지는 않는다.
사실 대부분의 경우 state 변경이 발생하면 state 갱신에 대한 schedule 작업은 매우 빠르게 일어난다.
실제로 순식간에 발생하는데, 인간이 보기에는 거의 즉시 처리된 것처럼 보인다.
하지만 React는 이러한 state 변화를 지연시킨다.
대부분의 성능 기반의 작업들이 거의 동시에 진행되는 한편, React는 잠재적으로 더 높은 우선순위를 갖는 것을 목표로 한다.
사용자가 입력할 수 있는 공간(like Input)이 있다고 한다면, 사용자 입력에 응답하는 것이 화면의 문자를 변경하는 것보다 우선순위가 높다.
이러한 이유로 React는 예정된 state 변경을 연기할 수 있다.
React가 하는 일은 동일한 유형의 state에서 state 변화의 순서가 보장된다는 것이다.
언젠가 state 변화가 처리되고 React가 component를 재평가하고 component 함수를 실행한다.
이전의 state를 기반으로 state 변경
scheduling 때문에 다수의 scheduled state가 동시에 있을 수도 있다.
즉, 동시에 여러 번의 갱신이 schedule될 수도 있으므로 state를 갱신할 때는 함수 형태를 이용해서 갱신해야한다.
const dateChangeHandler = (event) => {
setUserInput((prevState) => {
return { ...prevState, enteredDate: event.target.value };
});
};
사실 많은 경우에 굉장히 빠르게 처리되기 때문에 큰 문제가 되지 않는다. 잠깐의 지연조차 느끼지 못하는 경우가 많다.
하지만 이론상으로 이 scheduling 작업은 지연될 수 있으므로 이전 state를 기반으로 state 변경이 이뤄진다면 가장 안전한 방법이다.
그렇지 않는다면 component 함수가 마지막으로 실행될 때의 state를 얻을 것인데, 예상한 결과값과 다를 수 있다.
완료되지 않은 state 변경 작업이 여러 개라면 component의 재렌더링 주기는 모두에게 동일하기 때문이다.
당연하게도 업데이트 작업이 처리되는 중간에는 새로운 component의 결과를 고려하지 않는다.
함수 형태를 사용해야 미완료된 state 변경 작업에 대해서 최신 상태를 유지할 수 있다.
한가지 예를 들어보자.
const navigateHandler = (navPath) => {
setCurrentNavPath(navPath) ;
setDrawerIsOpen(false) ;
} ;
여기서는 두 개의 state 업데이트를 호출했다. 이렇게 함수를 호출한다고 해서 바로 반영되는 것이 아니다.
이 경우 갱신 예약을 한 후에 component가 다시 실행되고 나서 사용 가능한 최신 state가 되는 것이다.
따라서, 이 두 업데이트 함수 사이에 시간 지연은 발생하지 않는다.
이와 같이 두 개의 코드들이 같은 곳에 있고 함께 state 갱신 호출을 한다면 React는 이 둘에 대한 state 갱신을 하나의 동기화 process에서 같이 실행된다.