애드블럭 종료 후 보실 수 있습니다.

ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Compound Component 패턴 (feat. React, Next.js)
    React 2024. 9. 21. 13:55
    728x90
    반응형

    Compound components는 React에서 더 표현력 있고 사용자 정의가 가능한 컴포넌트 API를 만들 수 있게 해주는 강력하고 유연한 패턴입니다.

    이 패턴은 특히 여러 관련 부분을 가진 복잡한 UI 컴포넌트를 구축할 때 유용합니다.

    이 개념에 대해 자세히 알아보고 Next.js에서 어떻게 구현할 수 있는지 살펴보겠습니다.

    Compound Components란 무엇인가?

    Compound components는 함께 작동하여 일관된 기능 단위를 형성하는 컴포넌트 그룹입니다.

    주요 아이디어는 공유 상태와 동작을 관리하는 부모 컴포넌트를 만들고, 자식 컴포넌트가 특정 부분의 렌더링을 처리하도록 하는 것입니다.

    Compound components 사용 시 주요 이점

    1. 향상된 유연성과 사용자 정의 가능성
    2. 관심사의 더 나은 분리
    3. 더 직관적이고 선언적인 API
    4. 향상된 재사용성

    React에서의 기본 예제

    사용자 정의 선택 컴포넌트에 대한 compound component 패턴의 간단한 예제로 시작해 보겠습니다.

    const Select = ({ children, onChange }) => {
      const [selectedOption, setSelectedOption] = useState(null);
    
      return (
        <SelectContext.Provider value={{ selectedOption, setSelectedOption, onChange }}>
          <div className="select">{children}</div>
        </SelectContext.Provider>
      );
    };
    
    const Option = ({ value, children }) => {
      const { selectedOption, setSelectedOption, onChange } = useContext(SelectContext);
    
      const handleClick = () => {
        setSelectedOption(value);
        onChange(value);
      };
    
      return (
        <div
          className={`option ${selectedOption === value ? 'selected' : ''}`}
          onClick={handleClick}
        >
          {children}
        </div>
      );
    };
    
    Select.Option = Option;
    
    // 사용 예
    <Select onChange={(value) => console.log(value)}>
      <Select.Option value="option1">옵션 1</Select.Option>
      <Select.Option value="option2">옵션 2</Select.Option>
      <Select.Option value="option3">옵션 3</Select.Option>
    </Select>

    Next.js에서 Compound Components 구현하기

    이제 Next.js 애플리케이션에서 더 복잡한 compound component 패턴을 구현하는 방법을 살펴보겠습니다.

    예시로 Tabs 컴포넌트를 만들어 보겠습니다.

    // components/Tabs.js
    import React, { createContext, useContext, useState } from 'react';
    
    const TabsContext = createContext();
    
    export const Tabs = ({ children, defaultTab }) => {
      const [activeTab, setActiveTab] = useState(defaultTab);
    
      return (
        <TabsContext.Provider value={{ activeTab, setActiveTab }}>
          <div className="tabs-container">{children}</div>
        </TabsContext.Provider>
      );
    };
    
    export const TabList = ({ children }) => {
      return <div className="tab-list">{children}</div>;
    };
    
    export const Tab = ({ children, tabId }) => {
      const { activeTab, setActiveTab } = useContext(TabsContext);
    
      return (
        <button
          className={`tab ${activeTab === tabId ? 'active' : ''}`}
          onClick={() => setActiveTab(tabId)}
        >
          {children}
        </button>
      );
    };
    
    export const TabPanels = ({ children }) => {
      return <div className="tab-panels">{children}</div>;
    };
    
    export const TabPanel = ({ children, tabId }) => {
      const { activeTab } = useContext(TabsContext);
    
      if (activeTab !== tabId) return null;
    
      return <div className="tab-panel">{children}</div>;
    };

     

    이제 이 compound component를 Next.js 페이지에서 사용해 보겠습니다.

    // pages/example-tabs.js
    import { Tabs, TabList, Tab, TabPanels, TabPanel } from '../components/Tabs';
    
    export default function ExampleTabs() {
      return (
        <div>
          <h1>탭 예제</h1>
          <Tabs defaultTab="tab1">
            <TabList>
              <Tab tabId="tab1">탭 1</Tab>
              <Tab tabId="tab2">탭 2</Tab>
              <Tab tabId="tab3">탭 3</Tab>
            </TabList>
            <TabPanels>
              <TabPanel tabId="tab1">
                <h2>탭 1의 내용</h2>
                <p>이것은 첫 번째 탭의 내용입니다.</p>
              </TabPanel>
              <TabPanel tabId="tab2">
                <h2>탭 2의 내용</h2>
                <p>이것은 두 번째 탭의 내용입니다.</p>
              </TabPanel>
              <TabPanel tabId="tab3">
                <h2>탭 3의 내용</h2>
                <p>이것은 세 번째 탭의 내용입니다.</p>
              </TabPanel>
            </TabPanels>
          </Tabs>
        </div>
      );
    }

     

    이 예제에서는 compound component 패턴을 사용하여 유연하고 재사용 가능한 Tabs 컴포넌트를 만들었습니다.

    주요 Tabs 컴포넌트가 상태를 관리하고, 자식 컴포넌트(TabList, Tab, TabPanels, TabPanel)가 특정 렌더링 작업을 처리합니다.

     

    Compound component 패턴은 React와 Next.js에서 유연하고 사용자 정의 가능한 컴포넌트를 만드는 강력한 기술입니다.

    이 패턴을 사용하면 복잡한 컴포넌트에 대해 더 직관적인 API를 만들고, 코드 구성을 개선하며, 재사용성을 향상할 수 있습니다.

    Next.js 예제에서 보인 것처럼, 이 패턴은 Next.js 애플리케이션에서 쉽게 구현하고 사용할 수 있으며, 정교한 UI 컴포넌트를 구축하는 깔끔하고 선언적인 방법을 제공합니다.

    반응형

    댓글

Designed by Tistory.