Reducing Prop Drilling Layer

현진·2023년 3월 13일
6
post-thumbnail

이 글에서는 UI의 구성을 통해서 Prop Drilling Layer를 얇게 구성하는 방법을 알아봅니다.

메인 컨셉은 children prop을 사용해서 하위 컴포넌트를 상위 컴포넌트에 직접 노출시켜 props를 전달하기만 하는 컴포넌트를 최소화하는 것입니다.

export default function App() {
  const [data, setData] = useState('hello')
  
  return (
    <div>
      <Header/>
      <div>
        <SideBar/>
        <Main data={data}/>
      </div>
      <Footer/>
    <div/>
  )
}

하나의 페이지를 구성하는 App 컴포넌트를 위와 같은 형태로 추상화 시켰습니다. Header, Sidebar, Main, Footer로 섹션을 구분하였고 각각은 하위 컴포넌트들을 가지게 됩니다.

이때 Main 컴포넌트에서 data라는 prop을 필요로해서 data를 prop으로 내려주었습니다.

export default function Main({ data }) {
  return (
    <main>
      <span>Main</span>
      <Card data={data} />
    </main>
  );
}

function Card( { data } ) {
  return (
    <div>{data}</div>
  )
}

Main 컴포넌트에서는 data를 prop으로 받아서 데이터를 사용하는 Card라는 컴포넌트에게 전달합니다. 결국 Main 컴포넌트는 레이아웃을 잡기위한 역할 뿐만 아니라 데이터를 전달하는용으로도 사용되고 있습니다.

이런 데이터 전달용 컴포넌트를 사용하지 않고 하위 컴포넌트에서 상위 컴포넌트의 데이터에 직접 접근하는 벙법에는 리액트에서 제공하는Context API가 있습니다.

하지만 Context API를 도입하기 이전에 리액트의 특성(Composition)을 사용해서 코드 UI 구조를 개선할 수 있습니다.

Composition

합성(Composition)은 컴포넌트안에 컴포넌트를 담을 수 있다는 것입니다. 리액트에서는 children prop을 이용하여 자식 요소를 그대로 전달할 수 있습니다.

export default function Main({ children }) {
  return (
    <main>
      <span>Main</span>
      { children }
    </main>
  );
}

Main 컴포넌트는 레이아웃이라는 역할만 하도록 하고 자식은 children prop을 통해 전달 받는 것입니다.

export default function App() {
  const [data, setData] = useState('hello')
  
  return (
    <div>
      <Header/>
      <div>
        <SideBar/>
        <Main>
          <Card data={data} />
        </Main>
      </div>
      <Footer/>
    <div/>
  )
}

이렇게 하면 상위 레벨의 컴포넌트에서 하위 레벨의 컴포넌트에게 prop을 직접 전달할 수 있습니다. 불필요한 layer를 거치지 않고도 말이죠.

prop을 전달해서 리액트 애플리케이션을 구성하는 것은 자연스럽습니다.(컴포넌트가 필요한 데이터를 전달받아 UI를 구성) 하지만 props를 전달만하는 컴포넌트가 생기는 경우 children prop을 활용한 UI 구조 개선을 통해 props 전달 레이어를 얇게 만들 수 있습니다.

기존에는 2개의 Layer를 거쳐서 props drilling이 이루어졌습니다. 따라서 상위 컴포넌트에서 하위 컴포넌트를 직관적으로 내려다 볼 수 없었습니다. 따라서 prop drilling이 필요했죠.(춘식이가 Level 1까지 밖에 보지 못합니다.)

UI 구조 개선을 통해 상위 컴포넌트에 하위 컴포넌트를 노출시켜서 원하는 컴포넌트에 원하는 props를 전달할 수 있습니다. 또한 이러한 구조 개선이 Context API나 전역 상태 라이브러리를 도입하기 전에 이루어져야 한다고 생각합니다.(우리가 구조를 노출시켰기 때문에 춘식이가 하위 컴포넌트의 구조까지 파악할 수 있습니다.)

Referecne

Passing Data Deeply with Context - React Docs
Composition vs Inheritance - React Docs

0개의 댓글