[React] Custom Component (1) - CDD, CSS 방법론, Styled Components

선정·2022년 6월 30일
0

Today I Learned

  • CDD (Component Driven Development)
  • CSS 방법론
  • Styled Components 사용하기

CDD (Component Driven Development)

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


CSS 방법론

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

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

1. SASS(Syntactically Awesome Style Sheets)

CSS를 확장해 주는 스크립팅 언어이며 CSS 전처리기 중에서 가장 유명하다. 두가지의 확장자 (.scss/.sass) 를 지원하는데, 보통 scss 문법이 더 많이 사용된다.


CSS

.dv1 {width:1000px;margin:0 auto;border:1px solid black}
.dv2 {width:200px;border:1px solid black}
.dv3 {width:500px;float:left;border:1px solid black}

SASS

$bLine:1px solid black; /* 변수 선언 */
 
.dv1 {width:1000px;margin:0 auto;border:$bLine}
.dv2 {width:200px;border:$bLine}
.dv3 {width:500px;float:left;border:$bLine}

장점
1) 변수 사용 가능 ➡️ 유지보수 용이
2) 중복 되는 코드를 줄일 수 있음

단점
1) CSS로 변환되는 과정을 알기 어려워 디버깅이 어려움
2) CSS에 비해 줄었지만 여전히 코드양이 많음
3) 기능이 많아서 용량이 큼



2. BEM

CSS 전처리기의 문제점을 보완하기 위해 BEM, OOCSS, SMACSS 같은 CSS 방법론이 등장했다. 각각의 장단점이 있으나 결국 세 방법론 모두 같은 지향점을 가진다.

  • 코드의 재사용
  • 코드의 간결화 (유지 보수 용이)
  • 코드의 확장성
  • 코드의 예측성 (클래스 명으로 의미 예측)

그 중 BEM은 대표적인 CSS 방법론이다. Block, Element, Modifier로 구분하여 클래스명을 작성하는 방법이며, Block, Element, Modifier 각각은 __로 구분한다.


/* 작성 방법 */
.block-element__modifier {
	/* css 내용 */
}

/* 작성 예시 */
.header-navigation__nav-text {
	color: white;
}

장점
1) 직관적인 클래스명을 통해 구조를 파악할 수 있음
2) 클래스명의 중복을 방지할 수 있음

단점
1) 클래스명이 길어져서 코드의 가독성이 떨어지고 용량이 커짐
2) 코드의 구조를 변경할 때 클래스명을 재수정하기 불편함



SASSBEM은 캡슐화(encapsulation : 객체의 속성과 행위를 하나로 묶고 실제 구현 내용 일부를 외부에 감추어 은닉하는 개념)의 개념이 없어 개발자들은 클래스명이 겹치지 않도록 관리해야 했다. 이러한 단점을 보완하기 위해 CSS Modules이 나오게 됐다.

3. CSS Modules

CSS Modules을 사용하면 CSS 선택자가 중첩되는 것을 방지할 수 있다. CSS Modules.module.css 확장자를 사용해 CSS를 작성한다. 해당 CSS 파일을 불러올 때, CSS 선택자에 고유한 해시 문자열을 추가하여 중첩을 방지한다.


App.module.css

.App {
  background: black;
  color: white;
}

App.js

import React from "react";
import styles from "./App.module.css";

function App() {
  return <div className={styles.App}>App</div>
}

export default App;

장점
1) CSS 선택자 중복을 방지할 수 있음
2) CSS 네이밍 규칙이 간소화됨
3) 추가적인 라이브러리를 설치할 필요가 없음

단점
1) 한 곳에서 모두 작성하지 않고 따로 CSS 파일을 만들어야 해서 CSS 파일 수가 너무 많아짐



그리고 방대한 CSS 파일을 관리해야 하는 CSS Modules의 단점을 해결하기 위해 CSS-in-JS라는 방법론이 나오게 된다. CSS를 컴포넌트 영역으로 불러들이는 것이다. CSS-in-JS에는 대표적으로 Styled-Component가 있다.

4. Styled-Component

Styled-Component는 기능적 혹은 상태를 가진 컴포넌트들로부터 UI를 완전히 분리해 사용할 수 있는 아주 단순한 패턴을 제공한다.


App.js

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

const Circle = styled.div`
  width: 5rem;
  height: 5rem;
  background: ${props => props.color || "black"};
  border-radius: 50%;
`;

function App() {
  return <Circle color="blue" />;
}

export default App;

장점
1) 클래스명, 아이디명을 지을 필요가 없음
2) CSS 파일이 따로 필요 없음
3) JS 내부에서 스타일을 정의하므로 동적 스타일링을 하기에 더 편리함

단점
1) JS 파일의 코드양이 많아지고 JS의 번들 크기가 커짐
2) JS의 CSS 코드를 파싱하는 단계가 있어 빠른 페이지 업로드에 불리함
3) 퍼블리셔와 협업할 시, 어려움이 있음



Styled-Components 사용하기


Styled-Components 설치하기

1) 라이브러리 설치

npm install --save styled-componenets

// 또는
yarn add styled-components

2) package.json에 아래 코드 추가 (권장)
: 여러 버전이 설치돼서 발생하는 문제를 줄여줌

package.json

{
  "resolutions": {
    "styled-components": "^5"
  }
}


Styled Components 문법


1. 컴포넌트 만들기

import styled from 'styled-components'

const 컴포넌트명 = styled.태그종류`
  // css 속성
`

App.js

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

const Circle = styled.div`
  width: 5rem;
  height: 5rem;
  background: black;
  border-radius: 50%;
`;

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

export default App;

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

import styled from 'styled-components'

const 컴포넌트명 = styled(재활용할 컴포넌트)`
  // 추가할 css 속성
`

App.js

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

const Circle = styled.div`
  width: 5rem;
  height: 5rem;
  background: black;
  border-radius: 50%;
`;

const RedCircle = styled(Circle)`
  background: red;
`

function App() {
  return <RedCircle />;
}

export default App;

3. Props 활용하기

1) Props로 조건부 렌더링하기
App.js

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 값으로 렌더링하기
App.js

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. 전역 스타일 설정하기

App.js

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
starter

0개의 댓글