코딩 도구/프론트엔드 개발 (Frontend Development)

[React] 컴포넌트 설계 - Composition vs Inheritance & Context API

MKISOS 2025. 5. 21. 05:53
반응형

이번에는 리액트 컴포넌트 설계 철학 중 하나인 합성(Composition)상속(Inheritance) 에 대한 개념과 함께, Context API 를 통한 전역 상태 관리 방법까지 정리해보았다.


Composition vs Inheritance

리액트는 상속보다 합성을 권장한다. 다시 말해, 하나의 컴포넌트를 확장하기 위해 상속하는 방식보다는 여러 개의 컴포넌트를 조합해서 더 복잡한 UI를 구성하는 방식을 지향한다.

Composition (합성)

합성은 컴포넌트를 props.children 또는 특정 props를 통해 다른 컴포넌트 내부에 포함시키는 방식이다.

function Card(props) {
  return <div className="card">{props.children}</div>;
}

function Welcome() {
  return (
    <Card>
      <h1>환영합니다!</h1>
      <p>이곳은 리액트 학습 공간입니다.</p>
    </Card>
  );
}

이렇게 하면 Card 컴포넌트를 다양한 콘텐츠로 재사용할 수 있어 유연한 컴포넌트 설계가 가능하다.

Inheritance (상속)

클래스형 컴포넌트 기반에서 하위 클래스를 만들어 기능을 확장하는 방식이지만, 리액트에서는 잘 사용되지 않는다. 리액트는 UI 구조보다는 데이터 흐름 중심이기 때문에 구성요소를 조합하는 방식이 더 직관적이고 유연하다.


Context란?

리액트에서는 일반적으로 부모 → 자식으로 props를 통해 데이터를 전달한다. 하지만 컴포넌트 깊이가 깊어질수록 props 전달이 복잡해지는 문제가 생긴다. 이 문제를 해결하기 위해 등장한 것이 바로 Context API이다.

Context는 컴포넌트 트리 안에서 전역적으로 데이터를 전달할 수 있도록 도와주는 기능이다.


Context API 사용법

  1. Context 생성하기
const ThemeContext = React.createContext('light');
  1. Provider로 값 전달하기
function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}
  1. Consumer 또는 useContext로 값 사용하기
function Toolbar() {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <button className={theme}>테마 버튼</button>;
}
  • useContext는 함수형 컴포넌트에서 Context를 쉽게 사용할 수 있게 해준다.
  • 여러 Context를 중첩하여 사용할 수도 있고, 복잡한 앱 구조에서도 전역 상태를 깔끔하게 공유할 수 있다.

Composition을 중심으로 컴포넌트를 유연하게 조립하고, Context를 활용해 전역 상태를 정리하면 큰 프로젝트에서도 코드 구조가 안정적이고 가독성 좋게 유지된다.

반응형