배치 작업은 데이터를 실시간으로 처리하는게 아니라, 일괄적으로 모아서 한번에 처리하는 작업을 의미한다. 리액트에서는 상태를 배치 업데이트를 통해 관리한다.
React는 성능을 위해 여러 setState() 호출을 단일 업데이트로 한꺼번에 처리할 수 있습니다.
this.props와 this.state가 비동기적으로 업데이트될 수 있기 때문에 다음 state를 계산할 때 해당 값에 의존해서는 안 됩니다.
예를 들어, 다음 코드는 카운터 업데이트에 실패할 수 있습니다.// Wrong this.setState({ counter: this.state.counter + this.props.increment, });
상태 업데이트를 매번 수행하는 것이 아니라 요청을 여러개 모은 뒤 실행한다. 그래서 비동기로 동작하는 것이다.
이 말은 내가 setState를 하고 바로 그 상태로 어떤 동작을 한다면 원하는 값이 나오지 않을 수 있다는 말이다.
내부적으로 Object.assign 메서드를 사용한다고 하는데 이 메서드는 여러 객체를 인자로 넘기면 뒤에 나온 값으로 덮어씌워버리는 식으로 동작한다. 내가 setState를 한 시점의 값 에다가 여러 상태 변경 요청을 덮어씌워버리니까 여러 상태 변경 요청이 차례로 실행되지 않고, 마지막 요청의 값이 최종이 되는 것이다.
이를 수정하기 위해 객체보다는 함수를 인자로 사용하는 다른 형태의 setState()를 사용합니다. 그 함수는 이전 state를 첫 번째 인자로 받아들일 것이고, 업데이트가 적용된 시점의 props를 두 번째 인자로 받아들일 것입니다.
// Correct this.setState((state, props) => ({ counter: state.counter + props.increment }));
리액트 공식문서에는 이 이슈를 해결하는 방법도 알려주고 있다. setState의 인자로 값이 아닌 함수를 넘기게 되면 이 함수의 인자는 첫번째로는 prevState를 받게된다. 이전의 상태를 받아서 동작하기 때문에 차례로 동작하는 결과를 얻게된다.