안녕하세요, 오늘은 react의 가장 기본적인 제공 기능 중 하나인 리렌더링에 대해 이해해봅시다.
리렌더링을 제대로 이해하지 못하면, 예상치 못한 난관들을 많이 마주하게 됩니다.
예를 들어, 카드 게임 혹은 Flash Clicker(빠르게 순서대로 버튼을 누르는 게임) 라는 게임을 만든다고 가정해봅시다.
targetNumber인 다음 숫자에 해당하는 숫자를 키패드에서 찾아 빠르게 누르면 되는 기록 성취 게임입니다.
1) 숫자 1을 클릭하면 헤더의 오른쪽 부분에 있는 00:00 으로 포맷팅되어 있는 시간(초 단위)가 올라가고,
2) 동시에 '다음 숫자 : 1' 은 '다음 숫자 : 2' 로 변합니다.
3) 동시에 1이 위치한 버튼은 깜빡이는 애니메이션이 진행된 이후에, 10이상의 랜덤 숫자로 바뀝니다.
여기 제시된 1) 과 2) 와 3)은 동시에 진행되어야 합니다. 간단해보이나요?
게다가 헤더의 오른쪽 부분에 있는 Level을 변경하면
Level 2의 경우 4x4 로, Level 3의 경우 5x5로 모양이 변해야합니다. 즉, 리렌더링이 되어야 합니다.
리렌더링이 될 때 시간 초기화는 기본으로 되어야하고, 무조건 00:00 으로 초기화 되어야 합니다. 00:01 이면 버그입니다.
결국 동시성을 다뤄야하는 문제는 동기화를 다뤄야하는 문제로 직결되기 때문에, 반드시 리렌더링의 과정을 이해하고
useEffect의 실행 시점과 비동기 함수의 실행 시점을 이해해야 합니다.
리렌더링의 과정은 다음과 같습니다.
- Render phase: 새로운 Virtual DOM 을 이전의 것과 비교하고, 차이점을 찾아냅니다.
- Reconciliation: 차이점을 발견하면, 아주 효율적인 알고리즘을 통해 actual DOM 을 업데이트할 방법을 찾습니다.
- Commit phase: 변경사항을 real DOM에 적용합니다.
useEffect에 첫 번째 인자로 들어가는 콜백 함수는 "(리)렌더링을 마친 직후" 에 실행됩니다.
따라서 기존의 렌더링 흐름을 방해하지 않고, (리)렌더링되며 새롭게 변경된 부분을 사용한 로직을 구성할 수 있습니다.
설명하다보니 useEffect를 언제 사용하면 좋을 지 정리하고 싶어지는데, 그건 추후에 해보겠습니다.
비동기함수는 즉각적인 결과를 받을 수 없는 함수를 의미한다고 보면 됩니다.
서버로부터 데이터를 받아오거나, setTimeout과 같은 방식으로 고의적으로 함수 실행을 늦추는 경우 당연히 코드가 실행되자마자 결과를 받아올 수 없겠죠. 그래서 비동기 함수는 본질적으로는 동기적으로 처리되지 않는 함수를 의미합니다.
하지만 비동기 함수의 결과값을 받고, 그걸 활용해서 무언가 작업을 하고 싶다면 .then 메서드나 async-await을 이용하는 방법이 있습니다. 이것도 나중에 .. 다룰 수 있다면 다루겠습니다
어쨌든 본론으로 돌아오면, 비동기 함수는 동기 함수의 실행이 전부 끝난 뒤에, 쌓인 순서대로 실행됩니다.
정확히 표현하자면 동기함수를 쌓아둔 call Stack이 텅 비게 되면, 비동기 함수를 적재해둔 큐(priority가 다른 2개의 큐 존재) 중에서 우선 순위가 높은 큐에서 차례대로 비동기 함수를 가져와 실행하게 됩니다.
더 자세히 이야기하려면 이벤트 루프와 관련된 이야기를 해야하는데, 그건 지금은 생략하도록 하겠습니다.
마지막으로 state는 변경하자마자 반영되는 것이 아니라, batch 단위로 state를 묶어 실행됩니다. (효율성을 위해)
이게 비동기적으로 느껴질 수 있지만, state는 사실 비동기적이진 않습니다. 다만 state의 변경 사항들을 최대한 한번에 가져가려고 하는 것 뿐이에요.
이제 useEffect의 실행 시점, 비동기 함수(setTimeout의 콜백함수)의 실행시점, setState로 인한 리렌더링의 시점을 이해했네요!
https://blog.logrocket.com/how-when-to-force-react-component-re-render/
https://react.dev/reference/react/useEffect
https://react.dev/reference/react/useState#updating-state-based-on-the-previous-state
'Develop > Frontend' 카테고리의 다른 글
퀴즈! 렌더링이 되지 않는 이유는? (Uncaught TypeError) (0) | 2024.11.19 |
---|---|
emotion에서 Theme 을 제대로 인식하지 못하는 에러 (+ 자동 완성도 불가능) (7) | 2024.11.10 |
React + Typescript 설치 시 생기는 에러 해결 (1) | 2024.11.10 |
Next.js 톺아보기 (3) | 2024.11.04 |
웹 빌드 도구와 번들러 , 그리고 번들링 프로세스 (0) | 2024.10.11 |