섹션 사이 구분선, 컴포넌트 대신 플래그로
data-driven 렌더링 config 설계
난이도: ★★☆☆☆ 연관 노트: sessionStorage 대신 URL에 상태를 담는 이유
핵심 요약
- JSX 삽입 방식은
map을 사용하지 못하고 직접 나열하거나,map을 유지하려면 배열을React.ReactNode타입의 컴포넌트 나열로 바꿔야 한다. - 플래그 방식은 divider 추가 시 수정하는 곳 = 해당 객체 값만 변경. JSX 삽입 방식은 배열에 새 컴포넌트 추가 + 배열 타입 변경까지 필요하다.
- 즉 플래그 방식은 변경이 데이터에 갇히고, JSX 삽입 방식은 변경이 렌더 구조까지 번진다.
왜 헷갈렸나
“관리가 편하다” 수준으로만 이해하고 있었다. 진짜 차이는 무엇을 수정하게 되는가였다 — 같은 “divider 하나 추가”인데 한쪽은 데이터 한 줄, 한쪽은 렌더 코드의 구조(배열 타입 포함)를 건드린다.
메커니즘
이미지 섹션을 나열하는 페이지에서 특정 섹션 앞에만 회색 구분 밴드가 필요했다.
선택지 A — JSX에 직접 삽입:
// map을 포기하고 직접 나열하거나
<Image src={a} />
<Image src={b} />
<Divider /> // ← 여기 끼우려고
<Image src={c} />
// map을 유지하려면 배열 자체를 ReactNode로
const items: ReactNode[] = [<Image .../>, <Divider />, <Image .../>];
선택지 B — 데이터에 플래그:
const SECTIONS: SectionItem[] = [
{ src: "a.png", alt: "..." },
{ src: "b.png", alt: "..." },
{ src: "c.png", alt: "...", dividerBefore: true }, // ← 이 줄만
];
{SECTIONS.map(({ src, alt, dividerBefore }) => (
<Fragment key={src}>
{dividerBefore && <Divider />}
<Image src={src} alt={alt} />
</Fragment>
))}
변경 파급 범위 비교:
divider 1개 추가 시 수정 범위
플래그 방식 ── 데이터 배열의 객체 1개 (렌더 코드 불변)
JSX 삽입 ── 렌더 구조 + 배열 타입 + key 전략 (구조 변경)
렌더 로직은 “규칙”(dividerBefore면 앞에 밴드)을 한 번만 정의하고, 이후의 모든 변주는 데이터가 흡수한다.
해결 패턴
interface SectionItem {
src: string;
alt: string;
/** 이미지 위에 구분선 렌더링 */
dividerBefore?: boolean;
}
주의: 이것도 3번 규칙(반복 3회부터 추상화)의 지배를 받는다. divider 위치가 하나뿐이고 앞으로도 없을 게 확실하면 JSX 직접 삽입이 더 단순할 수 있다. 이번 케이스는 “동일 템플릿을 쓰는 페이지가 3개”라 데이터 주도가 명확히 이겼다 — 페이지마다 divider 위치가 달라도 렌더 코드는 공유된다.
다음에 이 상황을 만나면
리스트 렌더링 사이에 “가끔” 끼어드는 요소가 생기면 → map을 끊기 전에 “이 변주를 데이터로 표현할 수 있나?”를 먼저 묻는다.
- 이 변주가 다른 아이템/다른 페이지에서도 반복될 수 있는가?
- 렌더 규칙(플래그 → UI)을 한 문장으로 말할 수 있는가?
- 플래그가 3개 이상 쌓이면 → 그때는 섹션 타입 분리(discriminated union)를 고려
커넥팅 닷
← 선행 개념 (이걸 알아야 이해된다)
- 선언적 렌더링 — “무엇을 그릴지”를 데이터로 선언하고 렌더는 규칙만 갖는 React의 기본 사고
- 관심사 분리(콘텐츠 vs 구조) — 콘텐츠(이미지 목록)는 페이지가, 구조(어떻게 나열할지)는 템플릿이 소유
→ 확장 개념 (여기서 더 나아가면)
- Discriminated Union으로 섹션 타입 분기 — 플래그가 늘어나면
{ type: "image" } | { type: "divider" }형태로 진화시키는 것이 정석 - 개방-폐쇄 원칙(OCP) — 렌더 코드는 수정에 닫혀 있고, 데이터 추가에는 열려 있는 구조
↔ 같은 원리가 적용되는 곳
- sessionStorage 대신 URL에 상태를 담는 이유 — “상태/변주를 어느 레이어에 두느냐”가 유지보수 반경을 결정한다는 공통 구조
- 라우트 config, 폼 스키마 렌더러 — 배열 config → 렌더 규칙 패턴의 대표 사례들
부록 — key 안정성
플래그 방식의 부수 이득: Fragment key={src}가 유지되므로 divider를 켜고 꺼도 이미지 노드의 key가 안 바뀐다. JSX 나열로 전환하면 index key로 밀리기 쉽고, 중간 삽입 시 이후 노드들이 전부 리마운트될 수 있다.