import { useState } from 'react';
export default function Counter() {
const [number, setNumber] = useState(0);
return (
<>
<h1>{number}</h1>
<button onClick={() => {
setNumber(number + 1);
setNumber(number + 1);
setNumber(number + 1);
}}>+3</button>
</>
)
}
위의 코드를 실행하면 setNumber(number + 1)를 세 번 호출하므로 “+3” 버튼을 클릭하면 세 번 증가할 것으로 예상할 수 있지만, 실제로 각 렌더링의 state 값은 고정되어 있으므로, 첫 번째 렌더링의 이벤트 핸들러의 number 값은 setNumber(1)을 몇 번 호출하든 항상 0이다. (이전 게시글 참고)
하지만 여기에는 한 가지 요인이 더 있는데, React는 state 업데이트를 하기 전에 이벤트 핸들러의 모든 코드가 실행될 때까지 기다린다.
setNumber() 호출이 완료된 이후에만 일어난다!
하지만, React는 클릭과 같은 여러 의도적인 이벤트에 대해서는 batch를 수행하지 않는다.
사용자가 서로 다른 시점에 발생시킨 별개의 클릭들까지 하나로 묶지는 않는다는 의미
배칭이 일어나는 경우: 하나의 클릭 핸들러 내부에서 상태 업데이트(setState)를 3번 호출하면, React는 이를 묶어서 리렌더링을 1번만 한다.
배칭이 일어나지 않는 경우: 사용자가 버튼을 '광클'해서 클릭 이벤트가 3번 발생했다면, 각 클릭은 독립적인 사건이기 때문에 React는 첫 번째 클릭에 대해 리렌더링을 완료하고, 그 다음 클릭을 처리한다.
setNumber(number + 1) 와 같은 다음 state 값을 전달하는 대신, setNumber(n => n + 1) 와 같이 이전 큐의 state를 기반으로 다음 state를 계산하는 함수를 전달할 수 있다. import { useState } from 'react';
export default function Counter() {
const [number, setNumber] = useState(0);
return (
<>
<h1>{number}</h1>
<button onClick={() => {
setNumber(n => n + 1);
setNumber(n => n + 1);
setNumber(n => n + 1);
}}>+3</button>
</>
)
}
n => n + 1을 업데이터 함수(updater function) 이라고 부른다.
React가 이벤트 핸들러를 수행하는 동안 여러 코드를 통해 작동하는 방식은 다음과 같다.
1. setNumber(n => n + 1): n => n + 1 함수를 큐에 추가한다.
2. setNumber(n => n + 1): n => n + 1 함수를 큐에 추가한다.
3. setNumber(n => n + 1): n => n + 1 함수를 큐에 추가한다.
다음 렌더링 중에 useState를 호출하면 React는 큐를 순회하는데, 이전 number state는 0 이었으므로 React는 이를 첫 번째 업데이터 함수에 n 인수로 전달한다. 그 다음 React는 이전 업데이터 함수의 반환값을 가져와서 다음 업데이터 함수에 n으로 전달하는 방식으로 반복한다.

React는 3을 최종 결과로 저장하고 useState에서 반환하기 때문에 위 예시에서 "+3"을 클릭하면 3씩 증가한다.
import { useState } from 'react';
export default function Counter() {
const [number, setNumber] = useState(0);
return (
<>
<h1>{number}</h1>
<button onClick={() => {
setNumber(number + 5);
setNumber(n => n + 1);
}}>Increase the number</button>
</>
)
}
이 경우에, 이벤트 핸들러는 React에 아래와 같은 작업을 지시한다.
setNumber(number + 5) : number는 0이므로 setNumber(0 + 5) => React는 큐에 “5로 바꾸기” 를 추가한다.setNumber(n => n + 1) : n => n + 1 는 업데이터 함수로, React는 해당 함수를 큐에 추가한다. 
결과적으로 React는 6을 최종 결과로 저장하고, useState 에서 반환한다.
import { useState } from 'react';
export default function Counter() {
const [number, setNumber] = useState(0);
return (
<>
<h1>{number}</h1>
<button onClick={() => {
setNumber(number + 5);
setNumber(n => n + 1);
setNumber(42);
}}>Increase the number</button>
</>
)
}

이 경우에는 React는 42를 최종 결과로 저장하고 useState에서 반환한다.
이벤트 핸들러가 완료되면 React는 리렌더링을 실행하고, 리렌더링하는 동안 React는 큐를 처리한다.
업데이터 함수는 렌더링 중에 실행되므로, 업데이터 함수는 순수해야 하며 결과만 반환해야 한다.
업데이터 함수 인수의 이름은 해당 ㄴtate 변수의 첫 글자로 지정하는 것이 일반적이다.
setEnabled(e => !e);
setLastName(ln => ln.toUpperCase());
setFriendCount(fc => fc * 2);