3주차 스터디
7~9장 · 3개 챕터
이번 주 핵심 요약
7장
-
JSX는 자바스크립트 표준 문법이 아닌, 결국 함수 호출을 더 쉽고 선언적으로 하기 위한 도구입니다. 즉, 실제 브라우저에서 실행되기 위해선 JSX가 JS로 변환되는 과정이 필요합니다.
-
React17 이전(클래식 런타임 환경)에는 트랜스파일러가 JSX 구문을 JS로 변환하는 데에 React.createElement()를 사용하였습니다. 이 말은 React가 import 되어야 했다는 것을 의미합니다. 17 버전부터는 자동 런타임이 도입되어 우리는 더이상 React import 구문이 필요하지 않게 되었습니다.
-
React를 전체 import하지 않아도 되어 번들 크기가 감소하고, 코드 라인이 감소하고, import 구문을 사용하지 않아 발생할 수 있는 에러가 사라지는 장점이 있습니다.
-
JSX -> JS 과정에서 사용되는 트랜스파일러는 babel, SWC, ESBuild 등이 예시로 소개됩니다. SWC는 Babel을 대체하는 관점에서 많이 사용되고, ESBuild의 경우 속도에 대해 강점이 있어서 Vite의 개발 모드에서 실행됩니다. 이 부분은 추후에 보강하겠지만, 빠른 변환 속도도 중요하지만 번들 크기, 빌드물의 정확도 등도 중요한 요소기 때문에 단순히 속도가 빠르다고 더 나은 도구라고 판단하지는 않습니다.
-
결과적으로 React.createElement() 혹은 jsx()의 경우 React Element라 불리는, 자바스크립트 객체가 변환되는 것을 알 수 있습니다.
-
React Element는 하나의 React Node를 반환해야 합니다. 다만 이 과정에서 불필요한 tag로 감싸게 될 경우 스타일이나 DOM Tree 상의 depth가 달라질 수 있습니다. <> (Fragment) 를 활용하여 감싸는 방식으로 문제를 해결할 수 있습니다.
-
React의 삼항 연산자는 조건부 렌더링에서 굉장히 유용하게 쓰입니다. && 연산자의 경우 0이나 NaN와 같이 쓰이는 경우, 화면에 표기할 수 있다고 판단되어 화면에 해당 값을 노출하기 때문입니다.
8장
- React 렌더링 과정을 조금 깊게 학습할 수 있었습니다. 마운트, 언마운트, 리렌더링 등이 어떤 개념인지에 대해 설명하며 React의 기본 사상에 대해 설명하고 있습니다.
- diffing 알고리즘의 원리에 대해 설명하고 있으며, key, type이 바뀐 경우 기존 element를 사용하지 않는다는 것을 알 수 있습니다. 즉, 이 경우는 리렌더링이 아닌 언마운트가 될 것입니다.
- 또한, 얕은 비교를 사용한다는 점도 알 수 있습니다. 원시값의 경우 값 비교, 객체 타입의 경우 주소를 비교합니다. 이 부분이 꽤 중요하다고 생각하는데, memo 함수를 쓰더라도 넘겨받는 props가 객체라 주소가 바뀌는 경우 memo 함수 자체가 무력화되는 경우가 생깁니다. 즉, onClick 함수를 props로 넘기는 경우 onClick 함수 자체를 useCallback으로 감싸지 않는 경우 memo로 감싼 하위 컴포넌트는 매번 리렌더링 될 것입니다. 이런 부분을 놓치지 말고 개발에 참고하면 좋을 것 같습니다.
- 다만, 커밋 과정에 대한 설명이 없는 것은 조금 아쉬웠습니다. 파이버 노드에서 계산된 결과물이 실제 DOM에 붙는 과정이 나왔다면 좀 더 이해가 쉽지 않았을까 하는 생각이 듭니다. 이 부분은 추가적인 학습이 필요하다고 생각합니다.
9장
- React 렌더링 규칙을 학습할 수 있었습니다. 책에서는 컴포넌트 렌더링 기준을 1) 최초 렌더링, 2) 부모 컴포넌트 변경, 3) state 변경 4) Context 변경으로 설명하고 있습니다.
- Context API 사용 시에는, useContext를 사용하여 구독하고 있는 컴포넌트라 리렌더링되고, 그 하위 컴포넌트들도 리렌더링되는 것을 알았습니다.
- props 변경 시에 리렌더링 되는 것은 왜 빠졌지? 라고 생각하였는데, useRef를 사용하여 props로 값을 넘겨주고, 그 값이 변하더라도 Child가 리렌더링되지 않는 것을 알 수 있었습니다.
- React에서는 불변성을 지켜야 하고, 순수 컴포넌트를 지향해야 합니다. 그렇기에 객체를 직접 수정하는 방식을 지양해야 하고, 사이드이펙트가 발생하는 로직의 경우 useEffect 구문으로 분리해야 합니다.