일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
31 |
- TypeScript
- virtaullist
- 리액트
- react
- Function Region
- 회고
- Webworker
- context.api
- provider 패턴
- 에세이
- 자바스크립트
- sharedworker
- 이것저것
- frontend
- 프론트엔드
- 아키텍처
- CustomHook
- MicroFrontEnd
- MFA
- 티스토리챌린지
- radixui
- JavaScript
- 웹워커
- CRA
- 오블완
- vite
- 리팩토링
- 클린코드
- Web
- 합성 컴포넌트
- Today
- Total
Lighthouse of FE beginner
[React] return condition && <></> 본문
보통은 삼항 연산자를 사용해 null을 리턴하거나 && 연산자를 사용해 랜더링을 하지만 Fragment가 빈 Element라고 생각하고 비어있는 Fragment를 리턴하는 경우도 있다.
사실 성능적으로 눈에 띄는 차이는 없지만 Fragment 또한 React에서 제공하는 API라는 점을 생각해야 한다.
Fragment?
React.Fragment란 리액트에서 제공하는 API이다. 컴포넌트를 만드는 경우 컴포넌트의 구성요소 들은 그룹화 되어야 한다. 리액트의 컴포넌트는 반드시 하나의 최상위 태그를 가지고 리턴되어야 하기 때문이다. 때로는 그룹화를 위해 html 태그를 사용하는 것이 낭비라고 생각될 수 있다. 자칫 잘못하면 <div> 태그가 무더기로 있는 컴포넌트를 확인할 수 있기 때문이다. 이때 그룹화를 위해 html 태그를 사용하는 것 보다 Fragment를 사용해 보다 효율적으로 컴포넌트를 구현할 수 있다.
<Fragment> (<>...</>) – React
The library for web and native user interfaces
ko.react.dev
Fragment가 Fiber노드로 파싱 되는 과정
createFiberFromElement 함수를 살펴보자.
export function createFiberFromElement(
element: ReactElement,
mode: TypeOfMode,
lanes: Lanes,
): Fiber {
let owner = null;
if (__DEV__) {
owner = element._owner;
}
const type = element.type;
const key = element.key;
const pendingProps = element.props;
const fiber = createFiberFromTypeAndProps(
type,
key,
pendingProps,
owner,
mode,
lanes,
);
if (__DEV__) {
fiber._debugOwner = element._owner;
if (enableOwnerStacks) {
fiber._debugStack = element._debugStack;
fiber._debugTask = element._debugTask;
}
}
return fiber;
}
위 코드를 살펴보면 createFiberFromTypeAndProps 함수에 태그와 키 props 등 여러 인자를 전달해 Fiber 노드를 생성한다. createFiberFromTypeAndProps 함수도 살펴보자.
export function createFiberFromTypeAndProps(
type: any, // React$ElementType
key: null | string,
pendingProps: any,
owner: null | ReactComponentInfo | Fiber,
mode: TypeOfMode,
lanes: Lanes,
): Fiber {
let fiberTag = FunctionComponent;
// The resolved type is set if we know what the final type will be. I.e. it's not lazy.
let resolvedType = type;
if (typeof type === 'function') {
... 중략
} else {
getTag: switch (type) {
case REACT_FRAGMENT_TYPE:
return createFiberFromFragment(pendingProps.children, mode, lanes, key);
... 중략
}
함수가 너무 길어서 살펴보고 싶은 부분만 발췌했다. tag가 REACT_FRAGMENT_TYPE 인 경우 createFiberFromFragment 함수를 호출한다. 마지막으로 해당 함수를 살펴보자.
export function createFiberFromFragment(
elements: ReactFragment,
mode: TypeOfMode,
lanes: Lanes,
key: null | string,
): Fiber {
const fiber = createFiber(Fragment, elements, key, mode);
fiber.lanes = lanes;
return fiber;
}
createFiberFromFragment 함수를 살펴보면 결국 Fragment도 파싱이 되어 Fiber 노드로 변환이 되는 걸 확인할 수 있다. 이 과정은 리액트의 재조정(reconciler) 과정 중 일부이다.
결국 조건부 랜더링을 위해 제공하는 React.Fragment 또한 재조정을 위해 Fiber 노드로 파싱이 되는 과정을 거친다는 것 이다.
결론
Fragment가 Fiber 노드로 파싱 되어 랜더링 단계를 수행되는 과정을 살펴봤다. 결국은 Fragment를 사용한다면 비어있는 컴포넌트, 혹은 화면을 랜더링 하기 위해서 위의 Fragment 파싱 과정을 거친다는 것 이다.
리액트에서 비어있는 컴포넌트를 랜더링 하는 경우 && 연산자와 null을 활용하는 것이 어떨까?
'[WEB] 프론트엔드' 카테고리의 다른 글
제작 UI 라이브러리 로컬 테스트 방법 (1) | 2024.07.12 |
---|---|
Vite 프로젝트 SWC 도입 (2) | 2024.07.10 |
Vite 프로젝트 번들링 최적화 (manualChunks) (2) | 2024.07.02 |
[트러블슈팅] Vite프로젝트에서 react-virtualized 사용 시 문제 (0) | 2024.07.02 |
[트러블슈팅] Vite 프로젝트 Node.js 환경 폴리필 (0) | 2024.07.02 |