딴 거 다 잊어도: React 컴포넌트 = element 반환하는 함수. JSX 는 그 element 를 nested 함수 호출 대신 HTML 모양 expression 으로 묘사하게 해주는 편의.
함수 in, element out
함수 컴포넌트는 인자 하나 — props object — 받고 React element (또는 fragment, null, element 배열) 반환. 계약은 그게 전부. 클래스 상속 없음, override 할 라이프사이클 메서드 없음, this 없음.
React 가 본인 컴포넌트가 지금 뭘 렌더할지 알아야 할 때마다 함수 호출. 출력은 UI 묘사이지 UI 자체가 아냐. React 의 reconciler 가 묘사들 비교해서 어떤 DOM mutation 할지 결정.
JSX 는 함수 호출로 desugar 됨
JSX 는 JavaScript 의 일부가 아냐. Vite + React 플러그인 (안에서 Babel 또는 SWC) 이 JSX 를 react/jsx-runtime 의 jsx()/jsxs() 호출로 transform. 그 호출 직접 쓸 일 거의 없지만, 존재한다는 걸 알면 그것들을 언급하는 에러 메시지가 덜 무서워.
Fragment 가 뭐
<>...</> (빈 태그 단축) 가 fragment. DOM wrapper 추가 없이 자식 묶음. 컴포넌트가 형제 element 여러 개 반환해야 하고 부모 <div> 가 레이아웃 오염시킬 때 사용.
조건 패턴
idiom 세 개가 조건 렌더링의 95% 커버:
{condition && <Foo />}— condition truthy 일 때만 Foo 렌더.{condition ? <A /> : <B />}— 하나 고름.{items.map(item => <Row key={item.id} {...item} />)}— 리스트 렌더.
리스트엔 key 필요. key 가 React reconciler 한테 '이 element 가 그 이전 element 에 대응' 이라고 알려서 remount 대신 move/update.
0/false 렌더링 함정
count === 0 일 때 {count && <Badge />} 는 DOM 에 literal 숫자 0 을 렌더해 (이유: 0 이 falsy → short-circuit 가 0 반환 → React 가 숫자를 텍스트로 렌더). 대신 {count > 0 && <Badge />} 또는 {Boolean(count) && <Badge />}.