일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
- useReducer
- heap
- react
- 리액트의 작동방식
- 프로그래머스
- MST구현
- Modern Javascript
- State
- codility
- DFS
- 리액트 상태값 업데이트
- 객체지향 설계 5원칙
- DB Navigator
- spread operator
- state update scheduling
- 섬 연결하기
- rest operator
- useContext
- 리액트 성능 최적화
- batch udpate
- Lifting State Up
- useState
- React 훅 사용규칙
- Greedy
- java
- Kruskal Algorithm
- JS Array Functions
- 프로그래머스#JAVA
- BOJ2042
- Segment Tree
- Today
- Total
개발하는SM
[React] State Update Scheduling & 일괄 업데이트 본문
서론
아래 코드에서 버튼을 눌렀을 때 <div> 에 찍히는 count 값은 왜 2이며 콘솔에 찍히는 count 값은 왜 1일까?
setCount(count+1) 을 3번 호출했으니 둘 다 4가 찍혀야 하는거 아닌가?
리액트에서 상태 갱신을 어떤 식으로 진행하며, 컴포넌트 재평가는 언제 일어나는지 알아보자.
React State Update Scheduling
리액트는 상태 갱신을 어떻게 할까?
useState 훅에서 리턴되는 set 함수를 호출했을 때 즉각적으로 상태값이 변경되지는 않는다.
상태 업데이트를 "스케줄링" 하게 된다.
또한, 함수 호출 시 '리액트에서 관리하는 상태값'을 먼저 변경하며 우리 코드에 있는 상태값을 변경하지는 않는다.
우리 코드에 있는 상태값은 컴포넌트가 재실행되면서 '리액트에서 관리하는 상태값' 으로 변경되게 된다.
아래 그림의 예시를 통해 알아보자.
MyProduct 라는 컴포넌트가 있고, 해당 컴포넌트 내부에는 NewProduct 라는 State 가 있다.
해당 State 의 초기값은 'DVD' 이다.
const [newProduct, setNewProduct] = useState('DVD');
MyProduct 컴포넌트 내부에서 setNewProduct('Book') 을 호출하면, 즉각적으로 우리 코드에 있는 상태값이 변경되지는 않는다.
대신, React 에 newProduct의 상태를 'Book' 으로 업데이트하라고 스케줄링을 하게 된다.
React 에서는 새로운 상태값 ( 'Book' ) 이 기존 상태값 ( 'DVD' ) 와 다른 것을 확인하고 상태값을 Update 한 후에 MyProduct 컴포넌트를 재실행한다.
컴포넌트가 재실행되면, 리액트에서 업데이트된 상태값이 우리 코드에 있는 상태값에 반영된다.
즉, 서론에서 setCount(count + 1) 이 호출된 뒤에도 콘솔에 count 값이 1로 찍힌 이유는,
setCount 를 통해 상태값 변경 스케줄링이 된 이후 컴포넌트의 재실행이 일어나기 이전에 콘솔에 값을 찍어주었기 때문이다.
상태값 일괄 업데이트 ( Batch Update )
위에서 알아본 바에 따르면, 상태값 변경 함수는 크게 2가지 일을 처리한다.
1. 상태를 변경
2. 함수 컴포넌트를 재실행
그런데, 상태값 변경 함수를 호출할 때마다 함수 컴포넌트를 재실행하는 것은 문제가 될 수 있다.
위의 예시에서와 같이 setCount() 함수를 연속으로 3번 호출하는데, 각 라인마다 컴포넌트를 재실행하는 것은 비효율적이며 어떤 식으로 동작할지 예측하기도 어렵다.
따라서 리액트에서는 하나의 함수가 처음부터 끝까지 어떠한 콜백이나 프로미스 없이 수행된다면, 이 함수 내에서 발생하는 모든 상태 갱신 작업을 일괄로 처리한다.
위에서 Add Count 버튼을 눌렀을 때 <div> 내의 Count 값이 4가 아니라 2가 된 원인도 이 일괄 업데이트 때문이다.
리액트에서 가지고 있는 count 상태값이 1인 상태에서 count + 1 업데이트가 이루어졌기 때문이다.
이러한 현상을 해결하기 위해 상태 변경 함수에 "콜백 함수"를 전달하여 해결할 수 있다.
콜백 함수에는 언제나 최신 값이 인수로 전달된다는 것이 보장된다.
콜백 함수를 전달하는 로직으로 수정하면 아래와 같다.
정상적으로 4가 찍히는 것을 확인할 수 있으며, 컴포넌트가 재실행된 이후 코드 안의 count 값이 4로 찍히는 것도 확인할 수 있다.
정리
리액트에서 상태값 변경 함수가 호출되었을 때 상태 업데이트가 "스케줄링" 된다.
이 상태값 변경 함수는 아래 2가지 일을 수행한다.
1. 리액트에서 관리하는 상태값 업데이트
2. 이전 상태값과 새로운 상태값이 다를 경우 함수 컴포넌트 재실행 ( 이 때 코드 내의 상태값이 변경됨 )
리액트에서는 하나의 함수가 처음부터 끝까지 어떠한 콜백이나 프로미스 없이 수행된다면,
이 함수 내에서 발생하는 모든 상태 갱신 작업을 일괄로 처리한다.
컴포넌트가 리랜더링 되는 시점과 상태 변경이 예약되는 시점의 차이를 아는 것은 중요함.
참고
'Web > Front-End' 카테고리의 다른 글
[React] 리액트가 작동하는 방식과 성능 최적화 테크닉 (0) | 2023.04.05 |
---|---|
[Javascript] 자바스크립트의 동작방식 - 싱글스레드와 비동기 (0) | 2023.03.25 |
[React] Context API 와 useContext Hook (0) | 2023.03.20 |
[React] React 의 참조형 타입 State 관리와 Javascript 깊은 복사 (2) | 2023.03.19 |
[React] Hook 사용규칙 (0) | 2023.03.13 |