디자인 패턴 연구

React 2023. 7. 29. 01:29

가로 배치

웹 사이트를 돌아다니다 보면 위 그림과 같이 한 섹션에 여러 개의 카드 영역이 한 줄에 일정 간격을 두고 배치된 것을 본 적이 있을 것이다.

 

가로 배치 예시

위 캡처본과 같이 구글에서 검색 카테고리를 보여주는 부분인데, 이미지, 동영상.. 등과 같은 카테고리를 담고 있는 하나의 섹션이 있고, 섹션 안에 카테고리 아이템이 일정 간격을 두고 한 줄로 배치되어 있다.

 

아토믹 디자인 패턴을 공부하면서 해당 부분을 추상화하는 방법은 나름대로 연구해보았다.

 

먼저, 구글 검색 카테고리 영역을 보면 가장 먼저 떠오는 것이 카테고리아이템을 담을 전체 섹션과, 아이템을 한 줄로 배치해 줄 컴포넌트로 구성되어 있음을 알 수 있다.

 

그리고 먼저, 아톰에 해당하는 요소로 FlexBox, Section을 떠올렸고, FlexBox와 Section을 활용하여, 가로 배치를 해줄 컴포넌트인 분자 컴포넌트로 StackView를 구성해 보았다.

 

폴더 구성은 다음과 같다.

 

src/component/atoms/FlexBox/index.jsx

export default function FlexBox({
  direction = "row",
  flex = 1,
  gap,

  children,
}) {
  return (
    <>
      <div
        style={{
          display: "flex",
          flexDirection: direction,
          flex: flex,
          gap: gap,
        }}
      >
        {children}
      </div>
    </>
  );
}

 

src/component/atoms/Section/index.jsx

import { defaultCSS } from "style/global";

export default function Section({
  w,
  h,
  bgColor = defaultCSS.color.primary,
  margin,
  padding,
  border,
  children,
}) {
  return (
    <>
      <section
        style={{
          width: w,
          height: h,
          backgroundColor: bgColor,
          margin: margin,
          border: border,
          padding: padding,
        }}
      >
        {children}
      </section>
    </>
  );
}

src/component/molecules/StackView/index.jsx

import FlexBox from "component/atoms/FlexBox";
import Section from "component/atoms/Section";

export default function StackView({ gap, children }) {
  return (
    <>
      <Section bgColor="blue">
        <FlexBox gap="20px">
          {children.map((item, index) => (
            <FlexBox>
              <Section
                w="100%"
                bgColor="red"
                border="1px solid #0f0"
                key={index}
              >
                {item}
              </Section>
            </FlexBox>
          ))}
        </FlexBox>
      </Section>
    </>
  );
}

 

해당 컴포넌트를 구성할 때, 몇 가지 어려운 부분이 있었는데, Section에 Flex 관련 속성을 추가할 것인가? 아니면 Section에서 Flex관련 속성은 따로 빼서 FlexBox컴포넌트로 분리할 것인가? 를 고민을 했었다.

 

먼저, Section에 Flex속성을 같이 가지게 되면, Section의 원래 관심사는 구역을 나누는 것을 넘어서, 하위 요소들의 배치까지 신경을 쓰게 되지만, 하나의 컴포넌트로 Flex 속성을 처리할 수 있다는 장점이 있고

 

Section에서 Flex속성을 뺴서 FlexBox 컴포넌트로 만들게 되면, Section은 구역 분할에만 집중할 수 있고, FlexBox는 요소들의 배치에 신경 쓸 수 있게 된다. 이로 인해 Section과  FlexBox에서 관리하는 속성도 연관된 것들만 있게 되므로 유지보수도 용이하지만,

단점으로는 StackView 컴포넌트에서 보이는 것과 같이 Section 아래에 FlexBox 컴포넌트를 중첩하게 되므로, 프로젝트 경우에 따라서는 여러 컴포넌트가 중첩되면서 유지관리가 어려워질 수 있을 것 같다는 생각이 든다.

 

최종적으로 이를 활용하는 예제 코드는 다음과 같다.

src/page/main/index.jsx

import Section from "component/atoms/Section";
import StackView from "component/molecules/StackView";

export default function Main() {
  return (
    <>
      <Section margin="15px">
        <StackView gap="10px">
          <div>test1</div>
          <div>test2</div>
          <div>test3</div>
          <div>test4</div>
        </StackView>
      </Section>
    </>
  );
}

이렇게 보니 나쁘지는 않은 것 같다.