[React]컴포넌트 분리(기준, 방법, 중요성)
들어가며..
이번 시간에는 컴포넌트 분리하는 기준, 컴포넌트 분리가 중요한 이유 그리고 추가로 응집도와 결합도에 대해서 소개하겠습니다.
🌐컴포넌트란?
컴포넌트는 리액트 앱을 구성하는 기본 단위로, 재사용 가능한 UI 조각을 말합니다. 이 컴포넌트들은 각각 자체적인 렌더링 로직과 상태 관리를 가지며, 복잡한 UI를 구성하기 위해 서로 조합하고 재사용할 수 있습니다.

위의 그림에서 확인할 수 있듯이 레고의 블록처럼 이미 만들어진 컴포넌트들를 조합하여 화면을 구성할 수 있다.
🌐컴포넌트 분리란?
리액트에서 컴포넌트 분리는 크고 복잡한 컴포넌트를 더 작고 관리하기 쉬운 여러 개의 독립적인 하위 컴포넌트로 나누는 과정을 의미합니다.
리액트 컴포넌트 분리의 주된 이유(중요성):
재사용성 증가: 공통적인 기능을 가진 컴포넌트를 분리하여 다양한 곳에서 재사용할 수 있습니다. 이는 개발 시간을 단축하고 코드의 일관성을 유지하는 데 도움을 줍니다.
유지 관리 용이성: 작은 컴포넌트로 분리함으로써 각 컴포넌트를 독립적으로 이해하고 수정하기 쉬워집니다. 이는 전체 코드베이스의 복잡성을 줄이고 버그를 더 쉽게 식별하고 수정할 수 있게 합니다.
테스트 용이성: 작고 독립적인 컴포넌트는 테스트하기가 훨씬 간편합니다. 각 컴포넌트를 격리하여 테스트할 수 있으므로, 단위 테스트의 정확성과 효율성이 향상됩니다.
가독성 향상: 작은 컴포넌트는 다른 개발자들이 코드를 이해하고, 프로젝트에 기여하기 쉬워집니다.
컴포넌트 분리의 중요성은 이제 알겠어. 그래서 어떻게 하는건데??
🌐컴포넌트 분리 기준은?
1. 단일 책임 원칙 (Single Responsibility Principle)
단일 책임 원칙은 소프트웨어 디자인 원칙 중 하나로, 모든 클래스나 컴포넌트는 하나의 기능만을 담당해야 한다고 강조합니다. 이 원칙을 따르면, 각 컴포넌트는 하나의 작업만 수행하므로, 수정이 필요할 때 해당 컴포넌트만을 고치면 되기 때문에 유지보수가 쉬워집니다. 예를 들어, 사용자 정보를 처리하는 클래스는 사용자 데이터만을 관리하고, 출력 형식이나 데이터 검증 같은 다른 기능들은 다른 클래스에서 담당해야 합니다.
2. 재사용 가능성 (Reusability)
재사용 가능성은 코드의 일부분을 다른 프로젝트나 다른 부분에서도 사용할 수 있도록 하는 것을 목표로 합니다. 예를 들어, 날짜 선택기나 드롭다운 메뉴와 같은 UI 컴포넌트가 재사용성이 높은 예입니다. 이를 통해 개발 시간과 비용을 줄이고, 일관성 있는 사용자 경험을 제공할 수 있습니다.
3. 가독성 (Readability)
코드의 가독성을 높이는 것은 프로그램의 이해를 돕고, 다른 개발자가 코드를 더 쉽게 읽고 수정할 수 있게 합니다. 작고 독립적인 컴포넌트로 코드를 나누면, 각 부분의 기능이 명확해지며, 에러를 찾기 쉬워지고, 전체 구조를 이해하기 쉬워집니다.
4. 상태와 라이프사이클 (State and Lifecycle)
컴포넌트의 상태 관리와 라이프사이클은 특히 리액트 같은 UI 라이브러리에서 중요한 개념입니다. 컴포넌트는 자신의 상태를 내부적으로 관리할 수 있고, 상태 변화에 따라 적절한 라이프사이클 메서드가 호출됩니다. 이러한 메서드는 컴포넌트가 화면에 렌더링되기 전 후, 업데이트 되기 전 후, 제거되기 전에 실행되는 코드를 정의합니다.
5. UI 요소 (UI Components)
다양한 UI 요소를 별도의 컴포넌트로 분리하면, 각 요소가 독립적으로 개발되고 테스트될 수 있습니다. 이는 UI의 일관성을 유지하고, 복잡성을 관리하는 데 도움이 됩니다. 예를 들어, 버튼, 입력 필드, 레이아웃 구조 등을 각각 독립된 컴포넌트로 개발하여 필요한 곳에서 쉽게 재사용할 수 있습니다.
이러한 기준들을 통해 구현 과정에서의 복잡성을 줄이고, 더욱 효율적이고 유지보수가 쉬운 시스템을 구축할 수 있습니다.
🌐코드 예시(댓글 시스템)
// CommentList 컴포넌트 : 댓글 목록 표시
function CommentList({ comments }) {
return (
<ul>
{comments.map(comment => (
<Comment key={comment.id} comment={comment} />
))}
</ul>
);
}
// CommentForm 컴포넌트 : 댓글 작성
function CommentForm({ onSubmit }) {
const [content, setContent] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
onSubmit(content);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" value={content} onChange={(e) => setContent(e.target.value)} />
<button type="submit">댓글 작성</button>
</form>
);
}
// Comment 컴포넌트 : 개별 댓글 표시
function Comment({ comment }) {
return (
<li>
{comment.author} - {comment.content}
</li>
);
}이렇게 각 컴포넌트는 분리된 역할과 책임을 가지며, 이는 코드의 유지보수성을 높이고, 각 컴포넌트의 재사용성을 증가시킵니다.
이어서, 리액트 컴포넌트를 설계할 때 중요한 두 가지 개념인 '응집도'와 '결합도'에 대해 설명하겠습니다.
🌐응집도와 결합도
- 응집도 (Cohesion)
응집도는 하나의 컴포넌트 내부에 존재하는 요소들이 서로 얼마나 밀접하게 관련되어 있는지를 나타냅니다. 응집도가 높은 컴포넌트는 잘 정의된 목적을 가지고 있으며, 해당 컴포넌트 안의 모든 기능이 이 목적과 직접적으로 관련되어 있습니다. 응집도가 높으면 컴포넌트의 재사용성, 유지보수성, 이해하기 쉬움이 향상됩니다.
- 결합도 (Coupling)
결합도는 서로 다른 컴포넌트들 간의 의존성의 정도를 나타냅니다. 결합도가 낮은 시스템은 각 컴포넌트가 독립적으로 작동하며, 다른 컴포넌트와의 의존성이 적습니다. 결합도가 낮을수록 컴포넌트를 수정하거나 대체하기가 더 쉬워지고, 시스템의 유연성이 증가합니다.
=> 결론 : 응집도는 high, 결합도는 low하게
응집도는 높이고, 결합도는 낮춰야되는건 알겠어. 그래서 어떻게 하는건데?
🌐리액트에서의 응용
응집도 높이기
리액트에서 응집도를 높이기 위해 각 컴포넌트는 하나의 기능만을 수행하도록 설계합니다. 예를 들어, 게시글을 보여주는 컴포넌트는 게시글 데이터를 렌더링하는 것에만 집중하고, 데이터를 가져오는 로직은 다른 컴포넌트나 서비스 레이어가 담당하게 합니다.
결합도 낮추기
결합도를 낮추기 위해서는 컴포넌트 간에 데이터를 전달할 때 가능한 한 추상적인 인터페이스를 사용합니다. 예를 들어, 상위 컴포넌트가 하위 컴포넌트에게 데이터를 전달할 때, 구체적인 객체를 전달하기보다는 필요한 정보만을 포함하는 간단한 객체나 변수를 사용합니다. 또한, Redux와 같은 상태 관리 라이브러리를 사용하여 컴포넌트 간의 직접적인 데이터 전달을 줄일 수 있습니다.
이런 원칙들을 따르면 리액트 애플리케이션의 유지보수와 확장이 훨씬 쉬워질 수 있습니다.
🌐리뷰
막연하게 컴포넌트를 잘 분리해야 된다는 것은 알고 있었습니다. 그러나 분리하는 기준이 무엇인지, 왜 분리를 해야하는 것인지에 대해서는 정확히 알지 못했었는데, 이번 아티클 작성 기회를 통해서 컴포넌트 분리의 중요성과 필요성에 대해서 깊이 있게 이해할 수 있었습니다. 앞으로도 학습을 바탕으로 컴포넌트를 설계를 해야겠다고 생각했습니다.
참고자료
https://ctrlcccv.github.io/code/2024-03-05-component-split/
https://velog.io/@kshyeon123/Common-Low-Coupling-High-Cohesion

