team logo icon

컴포넌트를 분리하는 기준과 방법

컴포넌트 분리하는 기준과 방법입니다.

🍀 컴포넌트란 무엇인가?


컴포넌트(component)는 소프트웨어 개발에서 재사용 가능하고 독립적인 기능 또는 모듈을 말합니다. 리액트에서는 앱을 이루는 최소한의 단위를 뜻합니다.

🍀 리액트 컴포넌트를 분리하는 기준


  • 재사용 가능성

    비슷한 기능을 하는 부분은 독립된 컴포넌트로 분리하여 재사용성을 높입니다.

  • 복잡한 코드

    코드가 복잡하다면 가독성을 개선하고 유지보수 할 수 있게 만들기 위해 컴포넌트를 분리할 수 있습니다.

  • 단일 책임 원칙 (SRP)

  • 각 컴포넌트는 하나의 명확한 역할을 수행해야 합니다.

  • 상태 (랜더링 퍼포먼스)

    컴포넌트가 관리하는 상태를 고려하여 분리합니다.

  • UI요소

  • 컴포넌트는 UI를 독립적이고 재사용 가능한 조각으로 나눌 수 있습니다.

☑️ 재사용 가능한 컴포넌트를 만드는 방법

재사용 가능하다는 것은 일반적이라는 것을 의미합니다. 그러기 위해서는 아래의 사항들을 지켜줘야 합니다.

  1. 확장성이 있도록 설계해야 한다.

  2. attribute 명이 일반적이어야 한다.

  3. 도메인에 얽혀있으면 안된다.

위의 사항들을 잘 지켜주기 위해서는 재사용하려는 컴포넌트에는 정말 공통적인 것들만 남겨두고 사용하는 컴포넌트의 고유한 것은 속성(props)으로 전달하는 것입니다.

function Page1() {
  return (
      <div>
        <Card
          summary={<p>요약...</p>}
        />
      </div>
  );
}

function Page2() {
  return (
      <div>
        <Card ... />
      </div>
  );
}

function Card(props) {
  return (
    <>
      <h3>...</h3>
      <p>가격...</p>
      {props.summary}
    </>
  );
}

위의 코드를 보면 Card 라는 재사용 가능한 컴포넌트를 Page1, Page2 컴포넌트에서 사용하고 있습니다. 이때 summary를 보여주는 <p> 태그는 공통적인 속성이 아닌 고유한 속성이므로 props를 통해 전달해 컴포넌트를 재사용 가능하게 유지할 수 있습니다.

☑️ 복잡한 코드, 단일 책임 원칙

복잡한 코드를 가지게 되는 가장 큰 이유는 하나의 컴포넌트가 여러 기능을 갖는 경우입니다.

function Page(props) {
  // 선택한 탭을 변경하면 보여주는 내용을 변경합니다.
  // 페이징을 다룹니다.
  // 단어를 검색을 합니다.
  // 검색 조건 토글을 다룹니다.
  // 등등
}

예를 들어 이렇게 Page 컴포넌트가 4~5개의 기능을 다루고 있다면 코드는 매우 복잡해지고 기능간에 결합이 강하게 발생하여 수정이 쉽지 않아집니다. 따라서 우리는 컴포넌트를 기능에 맞게 나눠서 코드를 단순화 해야합니다.


Page 컴포넌트를 위와 같이 나눌 수 있는데 가장 중요한 점은 각 컴포넌트는 각자의 UI,기능에 대한 책임만을 가집니다. 그리고 C의 경로로 하위 컴포넌트끼리 소통하지 않고 소통은 무조건 A 경로, 즉 컨텐츠 컴포넌트와만 소통해야합니다.

☑️ 상태(랜더링 퍼포먼스)

하나의 컴포넌트 안에서 서로 영향을 주지 않는 상태가 여러가지 있으면 문제가 있다고 볼 수 있습니다.

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

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

위의 코드를 보면 두개의 state가 서로 영향을 주지 않지만 둘 중 하나의 상태에 변화가 일어나면 두개의 상태 모두 렌더링됩니다. 따라서 이런 경우 아래와 같이 분리해주면 좋습니다.

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>
  );
}

🍀 컴포넌트 분리가 중요한 이유


  • 단일 책임 원칙 (SRP) 구현

    각 컴포넌트는 하나의 명확한 역할을 수행하여 코드의 이해도와 유지보수성을 향상시킵니다

  • 재사용성 향상

    공통 기능을 가진 컴포넌트를 분리해 여러 페이지에서 재사용할 수 있습니다. 이로 인해 개발 시간을 줄일 수 있고 효율성이 증가합니다.

  • 가독성 증대

    코드를 작고 독립적인 컴포넌트로 나누어 코드의 가독성과 이해도를 높일 수 있습니다.

  • 테스트 용이성

    컴포넌트 단위 테스트를 쉽게 집중하여 개발하면서 협업 효율성을 높일 수 있습니다.

  • 확장성

    잘 분리된 컴포넌트는 앱의 다른 부분에 영향을 끼치지 않기 때문에 확장성이 증가합니다.




참고 자료

https://medium.com/@junep/프론트엔드-아키텍처-컴포넌트를-분리하는-기준과-방법-e7cf16bb157a

https://profy.dev/article/react-folder-structure

최신 아티클
lighthouse에 대해
문성희
|
2024.05.13
lighthouse에 대해
lighthouse에 대해
prettier, eslint, styleLint에 대해
이진
|
2024.05.10
prettier, eslint, styleLint에 대해
4주차 공유과제
Article Thumbnail
박채연
|
2024.05.10
Prettier, ESLint, StyleLint
prettier, eslint, stylelint