자바스크립트 - setState는 비동기이므로, 콜백 큐를 통해 실행되나요?
저는 React가 처음이고 setState가 내부적으로 어떻게 작동하는지 배우고 있었습니다. 그래서 이에 대해 몇 가지 질문을 하고 싶습니다. 첫째, setState는 항상 비동기적인가요? 만약 그렇지 않다면 일반적으로 어떤 상황에서 동기식으로 동작하나요? 둘째, setState에서 비동기 처리가 어떻게 발생하는지, 웹 API를 통해 실행되고 나서 콜백 큐로 넘어가는 방식인가요? 여러분, 이해가 안 되는 부분이 있다면 알려주세요. 정말로 여러분의 도움이 필요합니다.
답변 #1
네. 항상 비동기이며 결코 동기적이지 않습니다. 개발자들이 흔히 저지르는 실수는 이런 것입니다.
handleEvent(newValue) {
this.setState({ value: newValue }, () => {
// you can get the updated state here
console.log(this.state.value)
})
this.doSomething(newValue)
}
doSomething(newValue) {
// this.state.value is still the old value
if (this.state.value === newValue) {
// blabla
}
}
그리고 상태가 업데이트되는 데 얼마나 시간이 걸릴지 결정할 수 없습니다.
답변 #2
React setState는 항상 비동기적인 것은 아니며, 상태 변경이 어떻게 트리거되었는지에 따라 다릅니다.
1) 동기적 - 만약 동작이 Reactjs 외부에서 이루어지거나 상태 변경이 타이머 또는 사용자에 의해 유발된 이벤트 핸들러에 의해 트리거되었다면, Reactjs는 업데이트를 일괄 처리할 수 없으며 상태를 즉시 변경해야 합니다.
2) 비동기 만약 상태 변경이 onClick에 의해 트리거된다면, Reactjs는 성능 향상을 위해 상태 업데이트를 배치할 수 있습니다.
작동하는 코드샌드박스 링크
그리고
참조 게시물
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class App extends React.Component {
state = {
counter: 0
};
componentDidMount() {
// const intervalId = setInterval(this.updateState, 5000);
// this.setState({intervalId: intervalId});
this.counter.addEventListener("mousedown", this.updateState);
}
componentWillUnmount() {
this.counter.removeEventListener("mousedown", this.updateState);
// clearInterval(this.state.intervalId);
}
updateState = event => {
console.log("= = = = = = = = = = = =");
console.log("EVENT:", event ? event.type : "timer");
console.log("Pre-setState:", this.state.counter);
this.setState({
counter: this.state.counter + 1
});
console.log("Post-setState:", this.state.counter);
};
render() {
return (
<div className="App">
<span onClick={this.updateState} ref={elem => (this.counter = elem)}>
Counter at {this.state.counter}
</span>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
콘솔 로그
= = = = = = = = = = = =
EVENT: mousedown
Pre-setState:
0
Post-setState:
1
= = = = = = = = = = = =
EVENT: click
Pre-setState:
1
Post-setState:
1
콘솔 로그에서 볼 수 있듯이, mousedown 이벤트 상태 변경은 즉시 반영되지만 onClick 변경은 비동기적이거나, 더 정확히 말하면 일괄 처리됩니다.
그래서 상태 변경이 비동기적일 것이라고 가정하고, 버그를 피하기 위해 콜백 핸들러를 사용하는 것이 더 낫습니다. 그리고 물론 콜백 안의 모든 것은 자바스크립트에서 이벤트 루프를 거치게 됩니다.
도움이 되길 바래!!!
