
[React]컴포넌트를 분리하는 기준이 무엇일까?
[목차] 컴포넌트를 분리하는 기준과 방법
컴포넌트가 복잡해지는 이유는 무엇일까?
리액트 컴포넌트를 분리하는 기준은 무엇일까?
컴포넌트 분리가 중요한 이유는 무엇일까?
#1 컴포넌트가 복잡해지는 이유는 무엇일까?
큰 이유를 두개만 뽑자면 다음과 같다!
컴포넌트에 비지니스 로직이 있는 경우컴포넌트가 여러 책임을 갖는 경우
비즈니스 로직이 있는 경우
비즈니스 로직은 변경의 빈도가 UI의 변경의 빈도보다 더 느리다.
이러한 비즈니스 로직이 컴포넌트에 포함되어 있다면 빈번한 UI 변경에 따라 자주 영향을 받을 수 있다. 중요한 것은 "이러한 비즈니스 로직은 분리를 해야 한다"이다.
컴포넌트가 여러 책임을 갖는 경우
이 "책임"이라는 단어는 굉장히 많이 들어본 단어이다. 단일 책임, 단일 기능, 하나의 책임, 하나의 기능이라는 것은 무엇을 뜻하는 것일까? 굉장히 추상적이고 주관적인 개념이다.
리액트 공식문서의 Thinking in React에서는 컴포넌트는 이상적으로 한 번에 한 가지 일만 해야 한다고 설명한다.
그렇다면, 컴포넌트를 분리하는 기준은 무엇일까??
#2 컴포넌트를 분리하는 기준
공식 문서의 기준
UI 일부가 여러 번 사용되거나,UI 일부가 자체적으로 복잡한 경우분리하는 것이 좋다고 한다.
물론! UI를 기준을 잡는 것 외에 프로젝트마다 기준점을 어디에 잡는지에 따라 다양한 컴포넌트 분리 기준이 존재한다. ('View와 로직을 분리' 또는 'State에 따라서 분리' 등등...)
프로젝트에 적용하기 용이한 적절한 컴포넌트 분리 기준 예시는 다음과 같다.
해당 컴포넌트가 너무 길어서 가독성이 떨어지지 않는지?
다른 컴포넌트에서 재사용될 수 있는 컴포넌트인지?
#3 컴포넌트 분리가 중요한 이유는 무엇일까?
React.js에서 컴포넌트를 분리하는 것은 애플리케이션의 확장성, 유지보수성, 그리고 개발의 효율성을 향상시키는 핵심적인 방법 중 하나이다.
개발자가 애플리케이션의 다양한 부분을 더 작고 관리 가능한 단위로 나눌 수 있게 하며, 팀 작업에서도 협업을 용이하게 하는 장점이 있다.
코드로 예시를 보겠다.
재사용성
export function Button({ onClick, label }) {
return <button onClick={onClick}>{label}</button>;
}
동일한 구조의 버튼이 프로젝트 여러 곳에서 사용된다면 모든 컴포넌트에서 버튼 코드를 따로 작성하는 것 보다는 Button 컴포넌트를 따로 만들어두고 재사용하는 것이 편하다. 위 예시는 버튼 클릭시 실행될 onClick 함수와 버튼의 이름을 인자로 받아 사용하기 때문에 재사용이 가능해진다.
유지보수성
export function UserProfile({ user }) {
return (
<div>
<Avatar src={user.avatarUrl} />
<h1>{user.name}</h1>
</div>
);
}
이 가상의 UserProfile 컴포넌트는 상위 컴포넌트로부터 user 데이터를 받는다. Avatar 컴포넌트는 user 데이터의 아바타 이미지 url을 받아 이미지를 출력하는 역할을, 그 아래에서는 유저의 이름을 출력하고 있다.
만약 기능을 구현하면서 프로필 쪽의 무언가를 변경해야할 일이 생긴다면 UserProfile 컴포넌트를 바로 찾아서 바로바로 수정이 가능하다. 컴포넌트가 분리되어있지 않고 가령 User 컴포넌트에 모든 코드와 기능들이 밀집해 있다면 User 컴포넌트에 들어가서 프로필 부분을 찾는 것부터 시작해야한다. 코드와 기능의 복잡성이 늘어나면 늘어날 수록 필요한 파트를 찾는 시간과 노력이 커진다.
가독성
export function Layout({ header, content, footer }) {
return (
<div>
<Header/>
<Content/>
<Footer/>
</div>
);
}
이 가상의 레이아웃 컴포넌트는 어떤 프로젝트에서 페이지의 구성 요소들을 배치하는 역할을 수행한다. 페이지 최상단부터 헤더, 컨텐츠 내용, 푸터 영역을 갖도록 위치를 지정해준다.
컴포넌트를 분리하게 되면 한 페이지에 어떤 요소들이 어떻게 배치될 것인가의 '레이아웃' 문제를 위 예시처럼 간단하게 처리할 수 있다. 하나의 페이지 혹은 컴포넌트에서 하나의 문제만을 다룰 수 있어 코드를 관리하기가 한결 편안해진다.
테스트 용이성
// tests/Button.test.js
it('calls onClick when clicked', () => {
const onClick = jest.fn();
const { getByText } = render(<Button onClick={onClick} label="Click me" />);
fireEvent.click(getByText('Click me'));
expect(onClick).toHaveBeenCalled();
});
소프트웨어 테스트의 Unit Test를 실행한다고 생각해보자, 컴포넌트가 적절하게 분리되어 있다면 테스트를 실행하는 것도 아주 간편하다. 그렇지 않고 페이지 하나에 여러 기능과 UI들이 섞여있다면 Unit Test를 실시하기 이전에 각 요소들을 Unit 단위로 나누는 것부터 시작해야한다.
Reference
https://velog.io/@dygmm4288/TIL-컴포넌트를-분리하는-기준과-방법
https://velog.io/@skyoffly/개발-지식-React.js에서-컴포넌트를-분리하는-것
