(이벤트 핸들러가 비동기라고 해도) 상태 변수의 값은 렌더시 절대 변하지 않습니다. 렌더시 onClick 내부를 살펴보면,
const [number, setNumber] = useState(0);
// ...
return(
<button onClick={() => {
setNumber(number + 5);
setTimeout(() => {
alert(number);
}, 3000);
}}>+5</button>
)
number의 value는 setNumber(number + 5)
호출 뒤에도 0
입니다. 리액트가 컴포넌트를 호출하여 UI의스냅샷을 찍을 때
value는 고정되어 있습니다(fixed
)
사전: 일괄 처리
웨이터가 주문을 받을때를 생각해봅시다. 주문하나 받고 음식을 가져다주지 않고, 여러가지 주문을 한꺼번에 받고 나중에 음식을 가져다 줍니다.
이렇게 하면, 리렌더링을 계속하지 않고도 많은 컴포넌트의 많은 변수를 한꺼번에 업데이트 할 수 있습니다. 하지만, 이건 이벤트 핸들러나 안의 코드가 끝나지 않았다면 UI가 업데이트 되지 않는다는 것을 의미합니다. 이를 batching
이라고 합니다.
다음 값을 전달하지 않고, 큐(queue)에 있던 이전 값을 기반으로 다음 상태를 계산할 수 있는 함수를 넣으면 됩니다.
//이전
<button onClick={() => {
setNumber(number + 1);
setNumber(number + 1);
setNumber(number + 1);
}}>+3</button>
//이후
<button onClick={() => {
setNumber(n => n + 1);
setNumber(n => n + 1);
setNumber(n => n + 1);
}}>+3</button>
<button onClick={() => {
setNumber(number + 5);
setNumber(n => n + 1);
}}>Increase the number</button>
참고:
https://beta.reactjs.org/learn/state-as-a-snapshot
https://beta.reactjs.org/learn/queueing-a-series-of-state-updates