Blog

Read

Component Pattern

May 9, 2021

Reusable


리액트 컴포넌트를 만들다 보면, 어떻게 재활용 가능한 코드를 구현할 수 있을지 고민하게 됩니다. 실예로, 많은 사람들이 자주 사용하는 디자인 시스템들의 경우, 손쉽게 해당 UI를 재사용할 수 있게 해줍니다. 해당 컴포넌트를 사용하면서, API를 참조할 뿐, 내부 구현에 대해 신경쓰지 않고 사용합니다. 어떻게 해야 재사용 가능한 컴포넌트를 작성할 수 있을지에 대해 알아본 내용을 정리하겠습니다.


Context


리액트는 Hook 과 함께 function에서도 상태관리를 할 수 있게 되었으며, custom hook 을 사용해 재사용의 이점 또한 갖게 되었습니다. 그리고 Context API의 개발은, Redux와 같은 Flux 구조의 global 한 상태 관리가 아니어도, Prop drilling을 피할 수 있는 상태 관리 기능을 갖추게 되었습니다. 물론 Context를 사용하게 되면, Context를 사용한 특정 범위안에 스토어가 생기게 되어, Context를 벗어난 곳에서는 사용할 수 없다는 문제와, 재사용이 불가능한 컴포넌트가 된다는 문제점이 있습니다.


Compound Component

Think of compound component like the <select> and <option> elements in HTML. Apart they don't do too much, but together they allow you to create the complete experience. - Kent C.Dodds

Compound Component는 암묵적 상태를 공유하고, 컴포넌트 사용자에게는 유연성을 부여합니다. 내부 동작은 추상화 하고, 사용자에게는 재사용 가능한 컴포넌트의 로직을 신경쓰지 않도록 가능하게 해줍니다. 사용자는 그저, 해당 요소의 배치에만 관심을 갖으면 됩니다.


Implementation


요점은 이렇습니다. 재사용 가능하게 하기 위하여 Hook 과 Context 를 활용하는 것 입니다. 위에서 말했듯이, Hook은 재사용 가능하다는 이점이 있으며, context는 상태관리의 이점을 갖고 있습니다.

const TabsContext = React.createContext<ITabsContext>(undefined);

export const useTabs = (): ITabsContext => {
    const context = React.useContext(TabsContext);
    if (!context) {
        throw new Error(
            "이 컴포넌트는 <Tabs> 컴포넌트에서만 사용할 수 있습니다."
        );
    }
    return context;
};