setState가 비동기로 동작하는 이유에 대한 React팀의 답변

euneun·2021년 4월 30일
0

React

목록 보기
5/5
post-custom-banner

이 답변에 대해 내가 알아듣기 쉽게 번역해보았다.

Q. setState가 비동기적으로 동작하는 이유가 뭔가요?

A.

배치(일괄 처리)를 위해 재조정(reconciliation)을 지연시키는것이 더 이익이 크다.
setState()를 통한 re-rendering이 동기적으로 이루어지는것이 많은 상황에서 비효율적이며, 여러 업데이트들을 해야한다는 것을 알고 있다면 일괄적으로 처리하는것이 낫다.

예를 들어, 브라우저의 클릭 핸들러 내부에서 child와 parent가 모두 setState를 호출하는 경우에,
child를 두번 리렌더링하는 대신에, dirty라고 표시하고, 브라우저 이벤트를 종료하기 전에 한번에 리렌더링 한다.

당신은 이러한 의문을 가질 것이다 : 재조정이 끝날때까지 기다리지않고 바로 this.state에 setState 업데이트를 수행하면서 위에처럼 똑같은 일 (일괄처리)를 수행할 수는 없는가?
이에 대한 명확한 하나의 답은 없지만 몇가지 이유로 대답해줄 수 있다.

1. Guaranteeing Internal Consistency

-> 1. 내부 일관성 보장

state가 동기적으로 업데이트된다고 할지라도, props는 동기적으로 업데이트 되지 않는다.
(부모 컴포넌트를 리렌더링할때까지 props를 알 수 없으며, 이를 동기적으로 수행하게되면 일괄처리의 효용이 사라진다)

현재 React에서 제공하는 객체(state, props, refs)는 내부적으로 서로 일관성이 보장됩니다. 즉, 해당 객체들만 사용한다면 완전히 재조정된 트리를 참조하고 있다는것이 보장됩니다. 근데 이게 왜 중요할까요?

당신이 state만 사용하고, 당신이 제안했듯이 state가 동기적으로 flushed 된다면 아래와 같이 동작할것입니다.

console.log(this.state.value) // 0
this.setState({ value: this.state.value + 1 });
console.log(this.state.value) // 1
this.setState({ value: this.state.value + 1 });
console.log(this.state.value) // 2

그러나 몇몇의 컴포넌트에서 공유되려면, 이 state가 상위 항목으로 이동되어야 합니다.

이게 setState()에 의존하는 일반적인 React앱에서 전형적인 리팩토링 유형일것입니다.

그치만 이렇게 하게되면, 우리의 코드는 무너집니다.

console.log(this.props.value) // 0
this.props.onIncrement();
console.log(this.props.value) // 0
this.props.onIncrement();
console.log(this.props.value) // 0

왜냐하면, 당신이 제안한 모델에서는 this.state는 즉시 flush되지만 this.props는 즉시 flush되지 않기때문입니다.

또한 우리는 this.props를 부모의 리렌더링 없이는 즉시 flush할 수 없습니다. (이는 일괄처리를 포기해야한다는것을 의미하고, 경우에 따라 성능이 매우 저하될 수 있습니다.)

그래서 리액트팀에서는 이를 어떻게 해결했을까요?
리액트에서는, this.state와 this.props 모두 재조정과 flushing이 일어난 후에야 업데이트 됩니다.
따라서 당신은 0이 출력되는것을 볼 수 있었던것입니다.

2. Enabling Concurrent Updates

-> 2. 동시 업데이트 활성화

리액트에서는 setState() 콜에 대해, 상황에 따라 (이벤트 핸들러, 네트워크 응답, 애니메이션,등) 다른 우선순위를 부여할 수 있다.
예를들어, 메시지를 타이핑하고 있을때, 텍스트 박스안의 setState 콜은 즉시 flush되어야 한다. 그치만, 너가 메시지를 타이핑하고 있는 도중에 새로운 메시지를 받게된다면, 새로운 메시지의 렌더링을 지연시키는 것이 메시지 타이핑이 버벅거리게 되는것보다 낫다.

또한 이런 비동기적인 렌더링은 성능최적화뿐만이아니라, 유저의 경험측면에서도 더 낫다.

profile
제대로 짚고 넘어가자!🧐
post-custom-banner

0개의 댓글