한 줄 요약
거대한 페이지 컴포넌트를 합성 컴포넌트로 리팩토링했던 경험 공유
한 페이지 안에서 중복 코드가 너무 많다
최근 회사 코드(Svelte)를 보다가 한 페이지에서 반복되는 코드가 너무 많다는 걸 발견했다. 회사 코드를 그대로 갖다 붙이면 큰일나기 때문에, 예시를 통해 알아보자. 예를 들어, 같은 스타일과 로직을 가진 카드 UI가 여러 개 있었는데, 각각 따로 구현되어 있어서 유지보수가 어려웠다. 나는 이 문제를 해결하기 위해 합성(Composable) 컴포넌트 방식으로 리팩토링하기로 했다.
중복을 제거하고 더 재사용 가능한 구조로 만들기
내 목표는 다음과 같았다.
- 중복되는 UI와 로직을 컴포넌트로 분리한다.
- 다양한 데이터와 함께 재사용할 수 있도록 유연한 구조를 만든다.
- Svelte 코드와 React 코드로 비교하면서 더 나은 방식이 무엇인지 분석한다.
Svelte와 React 코드 비교하며 리팩토링하기
기존 Svelte 코드 (문제점이 있는 코드)
<Card>
<h2>{title1}</h2>
<p>{description1}</p>
<button on:click={handleClick1}>메뉴1</button>
</Card>
<Card>
<h2>{title2}</h2>
<p>{description2}</p>
<button on:click={handleClick2}>메뉴2</button>
</Card>
<Card>
<h2>{title3}</h2>
<p>{description3}</p>
<button on:click={handleClick3}>메뉴3</button>
</Card>
위 코드의 문제점은 단순하다.
title
, description
, handleClick
이 각각 다른 변수로 관리되고 있다.
카드의 레이아웃과 스타일이 동일한데도 불구하고, 같은 구조가 반복되고 있다.
리팩토링한 Svelte 코드 (합성 컴포넌트 적용)
<script>
export let title;
export let description;
export let onClick;
</script>
<Card>
<h2>{title}</h2>
<p>{description}</p>
<button on:click={onClick}>자세히 보기</button>
</Card>
<Card title={title1} description={description1} onClick={handleClick1} />
<Card title={title2} description={description2} onClick={handleClick2} />
<Card title={title3} description={description3} onClick={handleClick3} />
이제 <Card>
컴포넌트는 title
, description
, onClick
을 props로 받아 재사용할 수 있게 되었다.
React 코드로 같은 구조를 적용하면?
Svelte에서 적용한 방식을 React에서도 똑같이 적용할 수 있다.
const Card = ({ title, description, onClick }: { title: string; description: string; onClick: () => void }) => {
return (
<div className="p-4 border rounded-lg">
<h2>{title}</h2>
<p>{description}</p>
<button onClick={onClick}>자세히 보기</button>
</div>
);
};
<Card title="제목1" description="설명1" onClick={() => console.log("클릭1")} />
<Card title="제목2" description="설명2" onClick={() => console.log("클릭2")} />
<Card title="제목3" description="설명3" onClick={() => console.log("클릭3")} />
React에서는 props를 활용해서 같은 방식으로 합성 컴포넌트를 만들 수 있다.
여기서 Card 컴포넌트를 단순히 title, description, onClick을 받아서 렌더링하는 형태로 만들었다.
Result: 유지보수성이 높아지고, 코드가 간결해졌다
리팩토링 전에는 같은 UI를 여러 번 반복해서 작성해야 했지만, 리팩토링 후에는 Card 컴포넌트 하나만 만들어서 여러 곳에서 사용할 수 있게 되었다. 이 방식이 가지는 장점은 명확하다.
중복 코드 제거 → 한 번만 정의하면 어디서든 재사용 가능
유지보수 용이 → 디자인 변경이 생겨도 Card 컴포넌트만 수정하면 됨
더 나은 가독성 → 불필요한 반복이 줄어들어 읽기 쉬워짐
마무리
Svelte와 React는 문법적인 차이는 있지만, 합성 컴포넌트 개념을 적용하는 방식은 거의 비슷하다. 공통적으로 중복 코드를 최소화하고, 재사용성을 높이는 것이 중요하다. 실제로 이 방식으로 리팩토링한 이후, 코드 변경이 있을 때 수정해야 할 부분이 줄어들면서 개발 속도가 빨라졌다.
결국, 페이지 컴포넌트를 잘게 나누고, 필요한 데이터만 props로 넘겨주는 방식이 유지보수성과 확장성 측면에서 더 낫다는 걸 다시 한 번 깨닫게 되었다.
Top comments (0)