React에서 정상적으로 state
를 업데이트하려면 setState
함수를 사용해야 합니다. 다만 setState
의 비동기적 특성 때문에 원치 않는 결과를 가져올 때가 있기 때문에 이에 대한 이해가 필요합니다.
setState
메소드의 비동기적 동작 방식, 두 가지 인자에 대해 알아보도록 하겠습니다.
setState
는 위에서 언급했던 것처럼 state
를 비동기적으로 업데이트 합니다. 이는 setState
가 사용된 직후에 변경된 상태값이 적용되는 것이 아니라 이는 답변을 기다리는 하나의 요청이라고 생각하시면 됩니다.
그러므로 setState
를 호출한 직후 state
에 접근하시면 안됩니다. 아래의 코드를 보시면 이해가 쉬워지실 것이라 생각합니다.
handleClick() {
this.setState({
number: this.state.number + 1
})
console.log(this.state.number)
}
초기값이 0이라고 한다면, 위의 경우에 콘솔창에는 증가하는 숫자보다 항상 1이 작은 수를 보실 수 있게 됩니다. 이는 setState
는 비동기 처리이므로 호출이 끝났다고 해서 바로 상태가 +1로 업데이트가 되는 것이 아니라 시간이 얼마가 걸릴 지 모르는 하나의 요청인 것입니다.
그렇기 때문에 콘솔창에는 그 전의 값이 나타나게 되는 것입니다. 그렇다면, setState
의 직후의 값을 확인하는 방법은 무엇이 있을까요?
첫 번째 방법은 setState
함수의 두 번째 인자로 밖에서 콜백 함수를 넣어주는 것입니다. 비동기 처리가 끝날 때까지 기다렸다가 이후의 두 번째 인자로 넣어준 콜백 함수가 실행되는 원리입니다.
코드는 아래와 같이 확인할 수 있습니다.
handleClick() {
this.setState({
number: this.state.number + 1
}, () => {
console.log(this.state.number);
});
}
이는 바로 업데이트된 값이 콘솔창에 찍히는 것을 확인할 수 있습니다. 결국 number
가 다 업데이트되면, 이후의 콜백 함수가 실행되므로 콘솔창에서 업데이트된 값을 확인할 수 있는 것입니다.
업데이트된 값을 확인하는 데에 위의 방법인 두 번째 인자로 콜백함수를 넘겨받는 것은 썩 좋은 방법이 아닙니다. 계속해서 메소드 체이닝이 발생하게 되고 가독성이 떨어지는 코드를 작성하게 되기 때문입니다.
그렇다면, 더 좋은 방법은 무엇일까요?
this.state = {
text: '',
}
handleChange(e) {
this.setState({
text: e.target.value
}, () => {
console.log(this.state.text);
});
}
일단, 코드가 변경되었기 때문에 첫번째 방법인 콜백 함수로 업데이트된 값을 확인하는 방법을 예시로 들겠습니다. 그렇다면 더 좋은 방법은 무엇일까요? 굉장히 간단해서 놀라실 수도 있습니다.
handleChange(e) {
this.setState({
text: e.target.value
});
console.log(e.target.value)
}
바로 이처럼 상태값을 확인하는 것이 아니라 setState
를 통해 업데이트가 되는 값을 직접 콘솔창에 찍어보시면 방법이 해결됩니다. 어쩌면 허무하다고 생각하실 수 있지만, setState
의 비동기적 특성에 대해 쉽지만 확실하게 이해하실 수 있는 내용이라 생각합니다.
현재까지 저도 state
, setState
에 대해 이러한 특성을 완벽히 이해하지 못하고 사용했지만, 지금부터는 비동기적 특성을 이해하고 코드를 짤 수 있도록 해야할 것 같습니다.
setState
비동기 특성에 대한 추가적인 내용은 아래의 블로그를 참조해주시기 바랍니다.