[REACT] 어디까지 컴포넌트를 분리해야하는가? (2)

(해당 글은 이전 포스트와 이어지며, 하단 링크에 있는 글을 참고하여 학습한 내용을 정리한 포스트입니다)

 

프론트엔드 아키텍처: 컴포넌트를 분리하는 기준과 방법

컴포넌트를 언제 분리해야 하고 어떻게 분리해야 하는지 살펴봅니다.

medium.com

 

복잡한 컴포넌트

컴포넌트가 여러 책임을 갖는 경우

컴포넌트 분리 없이 만든 거대한 페이지 컴포넌트를 예시로 들 수 있겠습니다.

예시와는 알맞지 않지만, 이런 컴포넌트에서 페이징도 하고, 여러 기능이 추가적으로 달려있다고 가정해봅시다.

이런 경우라면 기능간에 결합이 강하게 발생해서 수정이 쉽지 않을 것 입니다. 글에서는 이를 서로 상호작용하는 기능이 많아지는 것보다 문제의 복잡성이 더 빨리 어려워지는 상황이라고 이야기를 하고있습니다.

 

따라서, 이런 경우에 컴포넌트를 책임에 맞게 나눠서 문제를 단순화 해야 합니다.

한 컴포넌트가 모든 책임을 갖지 않도록 기능을 나눠야 한다는 이야기지요

 

스스로와 관련된 변경은 각 컴포넌트가 책임짐으로써 감추고, 잘 변경되지 않는 외부와의 메시징은 제한하는 캡슐화는 컴포넌트를 관리하는 좋은 방법 중 하나이기에, 이런 경우에 컴포넌트를 분리하면 되겠습니다

 

컴포넌트에 비즈니스 로직이 있는 경우

일반적으로 유저 인터페이스와 비즈니스 로직은 변경의 속도가 다릅니다 (글에서는 빈도가 다르다고 표현하고 있습니다). 예를 들어 환불이 가능한 항목의 UI를 표시하는 방법은 많고 수시로 바뀔 수 있겠지만, 그 환불 자체를 결정하는 정책 자체는 잘 변하지 않습니다.

 

그렇기에, 컴포넌트에 비즈니스 로직이 포함되어 있다면 빈번한 UI 변경에 따라 자주 영향을 받을 수 있게됩니다.

비즈니스 로직은 현실 세계의 비즈니스 규칙이기때문에 영향을 자주 받고 변경에 노출되면 문제가 발생할 수 있습니다.

 

따라서 UI와 비즈니스 로직을 적절하게 분리하는 것은 유지보수적인 관점에서 매우 중요합니다.

 

렌더링 퍼포먼스

재사용과 복잡성 이외에 컴포넌트를 분리하면 좋은 기준 중 하나는 렌더링 퍼포먼스라고 합니다.

하나의 컴포넌트 안에서 서로 영향을 주지 않는 상태가 여럿 있다고 해보겠습니다.

 

function Page1() {
  const [카드 호버 상태, set카드 호버 상태] = useState(false);
  const [탭 호버 상태, set탭 호버 상태] = useState('none');

  return (
    ...
    <ul>탭</ul>
    ...
    <ul>카드</ul>
    ...
  );
}

 

탭과 카드는 서로 영향을 주지 않지만, 탭에 호버를 하면 카드들이 렌더링 되고 카드에 호버를 하면 탭이 렌더링 될 겁니다.

그리고 둘은 서로 영향을 주지 않습니다. 이런 경우에는 해당 로직들을 분리하면 됩니다.

 

function Page1() {
  return (
    ...
    <Tab></Tab>
    ...
    <ul>
      ...
      <li><Card></Card><li>
      ...
    </ul>
    ...
  );
}

function Tab() {
  const [탭 호버 상태, set탭 호버 상태] = useState('none');
  
  return (
    <ul>탭</ul>
  );
}

function Card() {
  const [카드 호버 상태, set카드 호버 상태] = useState(false);

  return (
    <section>...</section>
  );
}

여기까지가 해당 글의 작성자분께서 적어놓으신 개인만의 컴포넌트 분리 기준이었는데, 개인적으로는 막연하게 생각하던 컴포넌트 분리 기준을 구체적으로 생각할 수 있게 된 것 같습니다.

 

컴포넌트를 분리하는 과정에서 정확히 내려진 답은 존재하지 않겠으나, 해당 글을 읽고 정리하면서 나만의 기준을 만드는 좋은 기회가 된 것 같네요