이 글은 단순히 리액트 공식 문서를 읽고 베꼈을 뿐이다!! 학습 목적이라면 공식 문서를 보는 걸 추천한다.
공식 문서
https://react.dev/learn/queueing-a-series-of-state-updates
리액트는 상태 변경을 묶어서 처리한다
- 리액트는 이벤트 핸들러 내의 모든 코드가 실행되기를 기다린 후에 상태 업데이트를 진행
- 너무 많은 리렌더링을 일으키지 않고 여러 상태, 심지어는 다른 컴포넌트의 상태들까지 한번에 업데이트할 수 있음
- 이걸 "batching" 이라고 함
- 어플리케이션 속도 개선 가능
- 상태들이 업데이트 되다 만 상태에서 새로 렌더링하는 것을 방지
- (클릭처럼) 여러 번의 의도적인 사건들을 묶진(batch) 않음 -> 리액트가 묶어도 안전하겠다 싶을 때만 묶음
다음 렌더링 이전에 같은 상태를 여러 번 변경하고 싶을 때
- updater function을 쓰면 됨
setNumber((prev) => prev + 1);
이런 식으로- 이 함수가 실행될 때 현재 snapshot 값이 아닌 리액트에 저장된 각 상태의 가장 최신 값을 받아옴
- updater function은 순수해야 하고 결과값만을 반환해야 함
- Strict Mode에서는 updater function을 두 번씩 돌려서 순수성을 증명
- 여러 번 바꾸는 명령들은 전부 큐에 쌓임 -> 다음 렌더링에 큐를 계산해서 싹 비운 다음에 snapshot을 찍어서 전달
<button
onClick={() => {
setNumber(number + 5);
setNumber((prevNumber) => prevNumber + 1);
setNumber(number + 1);
}}
>
반가워요
</button>
현재 number
의 snapshot이 5
라고 할 때 실제 리액트 상태는 이런 순서로 바뀔 것이다.
setNumber(number + 5);
: 10으로 바꿈setNumber((prevNumber) => prevNumber + 1);
: 리액트가 갖고 있는 가장 최신 상태, 10을 받아서 11로 바꿈setNumber(number + 1);
: 현재 snapshot인 5에 1을 더한 6으로 바꿈- 결국 다음 렌더링에 받는
number
snapshot은6
여담) updater function argument의 네이밍
공식 문서에서는 updater function의 argument로 해당 상태 변수 이름의 앞글자를 따서 쓰라고 한다.
setEnabled(e => !e);
setLastName(ln => ln.reverse());
setFriendCount(fc => fc * 2);
소신발언: 이거 못생겼다고 생각한다.
난 prev뭐시기
를 애용하는데 이게 맞다는 건 아니지만 그래도 줄임말보다는 낫지 않나?
나중에 다른 사람들의 코드는 어떤 방식으로 쓰는지 보면 재미있을 것 같다.
여담2) 도전과제 재밌었다
'리액트 공식 문서 읽기' 카테고리의 다른 글
15화: Updating Arrays in State (0) | 2023.06.16 |
---|---|
14화: Updating Objects in State (2) | 2023.06.16 |
12화: State as a Snapshot (0) | 2023.06.15 |
11화: Render and Commit (0) | 2023.06.15 |
10화: State: A Component's Memory (0) | 2023.06.14 |