[React] [CDD]

전예훈·2023년 4월 19일
0

CDD (Component Driven Development)

페이지가 완성된 다음 다른 페이지에 적용되는 버튼에 대한 추가적인 기획안이 도착했다
이때 이전 페이지에서 사용했던 버튼을 똑같이 사용하도록 요청받았다면 여러 프로젝트, 팀간에 같은 UI 컴포넌트를 공유한다면 새로 만들어야 하나? 라는 고민을 하지 않아도 된다

디자인과 개발 단계에서부터 재사용할 수 있는 UI 컴포넌트를 미리 디자인하고 개발하면 이런 고민을 해결할 수 있고
고민 해결을 위해 등장한 개발 방법이 바로 Component Driven Development (CDD) 이다

레고처럼 조립해 나갈 수 있는 부품 단위로 UI 컴포넌트를 만들어 나가는 개발을 진행할 수 있다

CDD는 컴포넌트를 모듈 단위로 개발하여 UI 구축에 도달하는 개발 및 설계 방법론이다. 기본적인 컴포넌트 단위에서 시작해 페이지나 화면 수준까지 상향식(bottom-up)으로 UI를 구축하는 과정을 뜻한다.


CSS 방법론

프로젝트의 규모 확대 및 복잡도 증가와 모바일/태블릿을 비롯한 다양한 디바이스들의 등장으로, CSS가 복잡해짐에 따라 CSS를 구조화할 필요가 생기기 시작했다.

이 문제의 해결을 위해 CSS 전처리기(CSS Preprocessor)가 등장했다. 다양한 CSS 전처리기들이 있는데 이들은 CSS의 가독성과 재사용성을 높이고 유지보수성을 향상하기 위해 믹스인(mixin), 중첩 셀렉터(nesting selector), 상속 셀렉터(inheritance selector) 등과 같은, pure CSS에 존재하지 않는 기능들을 지원한다.

SASS

CSS 전처리기 중에서 가장 유명한 SASS는 Syntactically Awesome Style Sheets의 약자로 CSS를 확장해 주는 스크립팅 언어다.

자바스크립트처럼 특정 속성의 값을 변수로 선언하여 필요한 곳에 선언된 변수를 적용할 수도 있고, 반복되는 코드를 한번의 선언으로 여러곳에서 재사용 할 수 있도록 해주는 기능을 가졌다.

하지만 얼마 지나지 않아서 SASS가 ‘CSS의 구조화’를 해결해 주는 것의 장점보다 다른 문제들을 더 많이 만들어낸다는 것이 밝혀져서 잘 쓰이지는 않는다.


Bem

EM이란 Block, Element, Modifier로 구분하여 클래스명을 작성하는 방법이며, Block, Element, Modifier 각각은 —와 __ 로 구분한다.

클래스명은 BEM 방식의 이름을 여러 번 반복하여 재사용할 수 있도록 하며 HTML/CSS/SASS 파일에서도 더 일관된 코딩 구조를 만들어 준다.

하지만 이 방법론에서도 문제점이 발생되는데 클래스명 선택자가 장황해지고 긴 클래스명 때문에 마크업이 불필요하게 커지며, 재사용 하려고 할 때마다 모든 UI 컴포넌트를 명시적으로 확장해야 하는 단점이 존재 했다.

SASS 와 BEM도 고치지 못했던 몇 가지 문제들은 캡슐화의 개념이 없어졌고 이로인해서 개발자들이 유일한 클래스명을 선택하는 것에 의존할 수 밖에 없어졌다.


Styled Components

CSS in JS 라는 개념이 대두되면서 나온 라이브러리이다. 기존에는 HTML, CSS , JS 파일을 쪼개서 개발하던 방법에서 React 등의 라이브러리의 등장으로 컴포넌트 단위 개발이 주류가 되었고 CSS는 그렇지 못했다는 점에서 출발한 개념으로 정리 된다.

스타일 컴포넌트를 사용하면 JS파일 안에서 HTML, CSS, JS를 한꺼번에 개발할 수 있고 가장인기 있는 라이브러리 중하나이다.

Styled Components 문법

1.컴포넌트 만들기

import styled from "styled-components";

//Styled Components로 컴포넌트를 만들고
const BlueButton = styled.button`
  background-color: blue;
  color: white;
`;

export default function App() {
  // React 컴포넌트를 사용하듯이 사용하면 됩니다.
  return <BlueButton>Blue Button</BlueButton>;
}

2.컴포넌트를 재활용해서 새로운 컴포넌트 만들기

import styled from "styled-components";

const BlueButton = styled.button`
  background-color: blue;
  color: white;
`;

//만들어진 컴포넌트를 재활용해 컴포넌트를 만들 수 있습니다.
const BigBlueButton = styled(BlueButton)`
  padding: 10px;
  margin-top: 10px;
`;

//재활용한 컴포넌트를 재활용할 수도 있습니다.
const BigRedButton = styled(BigBlueButton)`
  background-color: red;
`;

export default function App() {
  return (
    <>
      <BlueButton>Blue Button</BlueButton>
      <br />
      <BigBlueButton>Big Blue Button</BigBlueButton>
      <br />
      <BigRedButton>Big Red Button</BigRedButton>
    </>
  );
}

props 활용하기

1) props로 조건부 렌더링하기

import React from "react";
import styled from "styled-components";

const Circle = styled.div`
  width: 5rem;
  height: 5rem;
  background: ${props => props.red ? "red" : "black"};
  border-radius: 50%;
  &:not(:first-child) {
    margin-top: 1rem;
  }
`;

function App() {
  return (
    <>
      <Circle />
      <Circle red />
    </>
  );
}

export default App;

2) props 값으로 렌더링하기

import React from 'react';
import styled from 'styled-components';

// 삼항 연산자
const Circle1 = styled.div`
  width: 5rem;
  height: 5rem;
  background: ${(props) => (props.color ? props.color : 'black')};
  border-radius: 50%;
  &:not(:first-child) {
    margin-top: 1rem;
  }
`;

// OR(||) 연산자
const Circle2 = styled.div`
  width: 5rem;
  height: 5rem;
  background: ${(props) => props.color || 'black'};
  border-radius: 50%;
  & + & {
    margin-top: 1rem;
  }
`;

const Circles = styled.div`
& + & {
  margin-top: 1rem;
}
`;

function App() {
  return (
    <>
      <Circles>
        <Circle1 />
        <Circle1 color="red" />
      </Circles>
      <Circles>
        <Circle2 />
        <Circle2 color="blue" />
      </Circles>
    </>
  );
}

export default App;

4.전역 스타일 설정하기


import React from "react";
import { createGlobalStyle } from "styled-components";

const GlobalStyle = createGlobalStyle`
	button {
		padding : 5px;
    margin : 2px;
    border-radius : 5px;
	}
`

// 전역 스타일을 정의한 <GlobalStyle> 컴포넌트를 최상위 컴포넌트에서 사용
function App() {
	return (
		<>
			<GlobalStyle />
			<Button>전역 스타일 적용하기</Button>
		</>
	);
}
profile
더욱더 QA스럽게!

1개의 댓글

comment-user-thumbnail
2023년 4월 19일

CDD구조화에 대해 저도 한번 더 정리되는 포스팅이네요! 👍

답글 달기