일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 실전프로젝트
- jQuery
- 동전 0
- db수정
- 중복선택
- server component
- 항해99솔직후기
- 카테고리필터
- 숫자를 별점으로
- 프로그래머스
- JavaScript
- 탐욕알고리즘
- 항해99후기
- 자바스크립트
- 중복카테고리
- 항해99
- 클라이언트 컴포넌트
- greedy
- NextJS v13
- 서버 컴포넌트
- 그리디
- 배열 메소드
- 백준
- react
- 부트캠프항해
- 날씨 api
- 로딩 후 실행
- 항해99추천
- 배열 중복 제거
- 알고리즘
- Today
- Total
공부 및 일상기록
[React] 리액트는 상태 변경을 어떻게 감지할까? 본문
함수형 컴포넌트에서는 useState를 이용해 setter 메소드를 통한 상태값을 변경한다. 그럼 React는 useState의 이전 상태값을 바탕으로 업데이트된 상태값을 비교해 변화를 감지한다.
먼저 다음의 경우를 생각해보자.
function Test = () => {
const [count, setCount] = useState(0)
return <div onClick={()=>setCount(count+1)} />
}
div를 한번 클릭하면 1이 늘어난다. 하지만 함수 안에 useState의 초기값이 0으로 설정되니 저걸 한번 더 읽으면 0이 되지 않을까?
당연히 아니다. 그럼 왜 아닐까?
그 이유는 클로저의 특징 때문이다.
클로저는 useState에서 중요한 개념이다.
브라우저는 파싱할때 한줄한줄 순서대로 코드를 실행하는데, 보통 변수가 선언되고 그 변수를 사용한 함수가 선언된다. 따라서 순서가 틀리면 실행이 안된다.
하지만 클로저는 코드 순서가 바뀌어도 변수를 잠깐 저장했다가 필요한곳에 저장해주는 개념이다.
useState의 상태값은 다음 렌더링까지 변하지 않는다. 아래의 코드를 또 보자
useEffect(()=>{
setCount(count+1);
console.log(count);
},[])
useEffect가 실행되면서 setCount를 통해 count+1을 진행하여도 콘솔에는 0이 찍힌다.
setCount는 메모리 어딘가에 있는 value값을 변경한 것이지 count가 변경된 것이 아니기 때문이다.
JS는 싱글스레드로 돌아가기 때문에 useEffect가 실행된 이후에 리렌더링이 진행될 것이다.
콘솔로그를 실행하는 시점에는 리렌더링이 진행되기 전이니 count 값은 0인 것이다.
렌더링은 언제 될까?
상태가 바뀔때마다 화면을 리렌더링 시켜야 한다면 문제가 많을 것이다.
그래서 리액트는 효율적으로 문제를 해결하기 위해 setState를 연속 호출하면 setState를 모두 취합(Batch)한 후에 한번에 렌더링 하도록 한다.
정확히는 16ms 단위로 batch update를 진행하고 그 사이에 변경된 상태값을 모아(merge) 이전 트리와 변경된 트리를 비교하는 작업 (재조정:reconciliation)을 거쳐 최종적으로 변경된 부분만 DOM에 적용 시킨다.
리액트에서 사용된 Batch
배치작업은 데이터를 실시간으로 처리하는것이 아닌 일괄적으로 모아서 처리하는 작업을 의미한다.
은행의 정산작업과 같은 업무에서 이런 일괄처리를 수행하게 되며 사용자에게 빠른 응답이 필요하지 않은 서비스에 적용할 수 있다.
'개발 > React' 카테고리의 다른 글
[React] Props Drilling 이란? 해결법은? (0) | 2023.01.09 |
---|---|
[React] JSX란 무엇인가? (0) | 2023.01.09 |
[React] 리액트와 JS의 비교 (0) | 2023.01.08 |
[React] 상태의 불변성이 중요한 이유 (1) | 2023.01.08 |
[React] 리액트란 무엇인가? (0) | 2023.01.08 |