[React]Custom component

nada_1221·2022년 8월 26일
0

공부

목록 보기
45/49

CDD


Component-Driven Development

프로잭트 중 이전에 요청 받았던 버튼을 똑같이 사용하도록 요청받았다.

여러 프로젝트 혹은 여러 팀 간에 같은 UI 컴포넌트를 공유한다면,
디자인과 개발 단계에서부터 재사용할 수 있는 UI 컴포넌트를 미리 디자인하고 개발하면 이런 고민을 해결할 수 있다.

이 고민을 해결하기 위해 등장한 개발 방법이 바로 Component Driven Development(CDD) 이다.
레고처럼 조립해 나갈 수 있는 부품 단위로 UI 컴포넌트를 반들어 나가는 개발을 진행할 수 있다.

CSS in JS



인터넷이 만들어진 이후 기술의 발달과 함께 사용자들은 다양한 환경(디바이스)에서 인터넷을 사용하기 시작했다.

이에따라 개발자들의 CSS 작성 방식도 꾸준히 진화해 오고 있다.

CSS 작업을 효율적으로 하기 위해 구조화된 CSS의 필요성이 대두되었고, CSS를 구조화하는 방법에 대한 연구가 필요해졌다.

CSS 전처리기 CSS Preprocessor 라는 개념이 등장했다.
CSS가 구조적으로 작성될 수 있도록 도움을 주는 도구이다.

여러가지 요인으로 CSS 문서는 양이 많아지고 이로 인해 이후 유지관리에 많은 영향을 끼친다.
이런 CSS의 문제점들을 프로그래밍 개념( 변수, 함수, 상속 등)을 활용하여 해결해 나갈 수 있다.

하지만 CSS 전처리기 자체만으로는 웹 서버가 인지하지 못하기 때문에 CSS 전처리기에 맞는 Compiler를 사용해야 하고 컴파일을 하게 되면 실제로 우리가 사용하는 CSS 문서로 변환이 된다.

이를 통해 CSS 파일들을 잘 구조화할 수 있게 되었고, 최소한 CSS 파일을 몇 개의 작은 파일로 분리할 수 있는 방법이 생겼다.

SASS

/** CSS **/
.alert(
  border: 1px solid color;
)
.button(
  color : color
)
/** --> SASS **/
$base-color: color
.alert(
  border: 1px solid $border-dark
)
.button(
  color: $border-dark
)

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

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

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

결국 전처리기가 내부에서 어떤 작업을 하는지 모른채로 스타일이 겹치는 문제를 해결하기 위해 단순히 계층 구조를 만들어 내는 것에 의지하게 되었고, 그 결과 컴파일 된 CSS의 용량은 어마어마하게 커지게 되었다.

CSS 방법론의 대두


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

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

- BEM


Block, Element, Modifier로 구분하여 클래스명을 작성하는 방법

  • Block : 전체를 감싸고 있는 블럭 요소
  • Element : 블럭이 포함하고 있는 한 조각
  • Modifier : 블럭 또는 요소의 속성

대표적인 CSS 방법론으로는 BEM이 있다.
BEM이란 Block, Element, Modifier로 구분하여 클래스명을 작성하는 방법이며, Block, Element, Modifier 각각은 --dhk __ 로 구분한다.
클래스명은 BEM 방식의 이름을 여러 번 반복하여 재사용할 수 있도록 하며 HTML/CSS/SASS 파일에서도 더 일관된 코딩 구조를 만들어 준다.

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

Encapsulation : 객체의 속성과 행위를 하나로 묶고 실제 구현 내용 일부를 외부에 감추어 은닉하는 개념

이 없다는 것이 문제점. 이로 인해 개발자들이 유일한 클래스명을 선택하는 것에 의존할 수 밖에 없었다.

CSS- in- JS의 등장 -Styled-Component


애플리케이션으로 개발 방향이 진화하면서 컴포넌트 단위의 개발은 캡슐화의 중요성을 불러왔다.
CSS를 컴포넌트 영역으로 불러들이기 위해서 CSS - in -JS가 탄생해서 이 문제를 정확하게 해결했다.

CSS-in-JS에는 대표적으로 Styled-Component가 있다.

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

특징장점단점
CSS기본적인 스타일링 방법-일관된 패턴을 갖기 어려움
!important의 남용
SASS
(preprocessor)
프로그래밍 방법론을 도입하며,
컴파일된 CSS를 만들어내는 전처리기
변수/함수/상속 개념을 활용하여
재사용 가능
CSS의 구조화
전처리 과정이 필요,
디버깅의 어려움이 있음
컴파일한 CSS파일이 거대해짐
BEMCSS 클래스명 작성에
일관된 패턴을 강제하는 방법론
네이밍으로 문제 해결,
전처리 과정 불필요
선택자의 이름이 장황하고,
클래스 목록이 너무 많아짐
Styled-Componet
(CSS-in-JS)
컴포넌트 기반으로
CSS를 작성할수 있게 도와주는
라이브러리
CSS를 컴포넌트 안으로 캡슐화,
네이밍이나 최적화를 신경 쓸 필요가 없음
빠른 페이지 로드에 불리함

Styled Components


Styled Components는 앞서 배운 CSS in JS라는 개념이 대두되면서 나온 라이브러리.

기존에 HTML,CSS,JS 로 쪼개서 개발하던 방법에서, React 등의 라이브러리의 등장으로 컴포넌트 단위 개발이 주류가 되었지만, CSS는 그렇지 못했단 점에서 출발한 개념.

CSS in JS 라이브러리를 사용하면 CSS도 쉽게 JS 안에 넣어줄 수 있으므로, HTML + JS + CSS까지 묶어서 하나의 JS 파일 안에서 컴포넌트 단위로 개발할 수 있게 된다.

이런 CSS in JS 라이브러리 중에서 현재 가장 인기 있는 라이브러리가 바로 Styled Components이다.

1. 컴포넌트 만들기


Styled Components로 컴포넌트를 만드는 방법은 다음과 같다.

const 컴포넌트이름 = styled.태그종류`
	CSS속성1 : 속성값;
	CSS속성2 : 속성값;
`

Styled Components는 ES6의 Templet Literals 문법을 사용한다. 즉, ' 이 아니라 백틱(`) 을 사용한다.

import styled from "styled-components";
//import 를 꼭 해주자.

//Styled Components로 컴포넌트를 만들고
const 컴포넌트이름 = styled.태그종류`
	CSS속성1 : 속성값;
	CSS속성2 : 속성값;
`

export default function App(){
 // React 컴포넌트를 사용하듯이 사용하면 된다.
  return <컴포넌트이름> 내용 </컴포넌트이름>;
}

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


const 컴포넌트이름 = styled(재활용할 컴포넌트)`
	추가할 CSS속성1:속성값;
	추가할 CSS속성2:속성값;
`

이미 만들어진 컴포넌트를 재활용해서 새로운 컴포넌트를 만들 수도 있다. 컴포넌트를 선언하고 styled()에 재활용할 컴포넌트를 전달해준 다음, 추가하고 싶은 스타일 속성을 작성해주면 된다.

import styled from "styled-components";
//import 를 꼭 해주자.

//Styled Components로 컴포넌트를 만들고
const 컴포넌트이름1 = styled.태그종류`
	CSS속성1 : 속성값;
	CSS속성2 : 속성값;
`

//만들어진 컴포넌트를 재활용해 컴포넌트를 만들 수 있다
const 컴포넌트이름2 = styled(컴포넌트이름1)`
	추가할 CSS속성1:속성값;
	추가할 CSS속성2:속성값;
`
//재활용한 컴포넌트를 재활용할 수도 있다.
const 컴포넌트이름3 = styled(컴포넌트이름2)`
	추가할 CSS속성1:속성값;
	추가할 CSS속성2:속성값;
`

export default function App() {
  return (
    <>
	  <컴포넌트이름> 내용 </컴포넌트이름>
      <br />
	  <컴포넌트이름2> 내용 </컴포넌트이름2>
      <br />
	  <컴포넌트이름3> 내용 </컴포넌트이름3>
    </>
  );
}

3. Props 활용하기


Styled Component로 만든 컴포넌트도 React 컴포넌트처럼 props를 내려줄 수 있다. 내려준 props 값에 따라서 컴포넌트를 렌더링하는 것도 가능하다.

const 컴포넌트이름 = styled.태그종류`
	css속성:${(props)=> 함수 코드}
`

Styled Components는 템플릿 리터럴 문법( ${ } )을 사용하여 JavaScript 코드를 사용할 수 있다. props를 받아오려면 props를 인자로 받는 함수를 만들어 사용하면 된다.

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

const 컴포넌트이름 = styled.태그종류`
	background:${(props)=> props.blue?"blue":"white"}
`

삼항연산자를 활용해 컴포넌트에 blue라는 props가 있는지 확인하고, 있으면 배경색으로 blue를 없으면 white를 지정해주는 예시코드.

2) Props 값으로 렌더링하기

props 값을 통째로 활용해서 컴포넌트 렌더링에 활용할 수 있다.

const 컴포넌트이름 = styled.태그종류`
	background:${(props)=> props.color?props.color:"white"}
`;
<styled.태그종류>내용1</stlyed.태그종류>
<styled.태그종류 color="red">내용2</stlyed.태그종류>
<styled.태그종류 color='yellow'>내용3</stlyed.태그종류>

똑같이 상항연산자를 사용하고 있지만, 이번에는 props.color가 없다면 white를, 있다면 props.color의 값을 그대로 가져와서 스타일 속성 값으로 리턴해준다.

const 컴포넌트이름 = styled.태그종류`
	background:${(props)=> props.color||"white"}
`;
<styled.태그종류>내용1</stlyed.태그종류>
<styled.태그종류 color="red">내용2</stlyed.태그종류>
<styled.태그종류 color='yellow'>내용3</stlyed.태그종류>

꼭 삼항연산자만 사용해야하는 것은 아니다. JS 코드라면 무엇이든 사용할 수 있으므로 원하는 값을 사용할 수 있도록 함수코드를 만들어서 사용하면 된다.

전역 스타일 설정하기


스타일을 컴포넌트로 만들 수 있다는 것은 좋지만, 전역에 스타일을 설정하고 싶을 땐 어떻게 하면 좋을까?

우선 전역 스타일을 설정하기 위해 Style Components에서 createGlobalStyle 함수를 불러온다.

import { createGlobalStyle } from "styled-components";

그 다음 이 함수를 사용해 CSS 파일에서 작성하듯 설정해주고 싶은 스타일을 작성한다.

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

이렇게 만들어진 <GlobalStyle> 컴포넌트를 최상위 컴포넌트에서 사용해주면 전역에 <GlobalStyle> 컴포넌트의 스타일이 적용된다.

function App(){
  return(
    <>
    	<GlobalStyle />
    	<input>전역 스타일 적용하기</input>
    </>
  )
}

컴포넌트 UI 개발을 위한 Storybook


Component Driven Development 가 트렌드로 자리 잡게 되면서 이를 지원하는 도구 중 하나인 컴포넌트 탐색기Component Explorer가 등장했다. Component Explorer에는 많은 UI 개발 도구가 다양하게 있는데 그 중 하나가 Storybook이다.

what is Storybook?

Component Dreven Development를 하기 위한 도구.
각각의 컴포넌트들을 따로 볼 수 있게 구성해주어 한 번에 하나의 컴포넌트에서 작업할 수 있다. 복잡한 개발 스택을 시작하거나, 특정 데이터를 데이터 베이스로 강제 이동하거나, 애플리케이션을 탐샐할 필요 없이 전체 UI를 한눈에 보고 개발할 수 있다.

why used Storybook or UI development tool?

Storybook은 기본적으로 독립적인 개발 환경에서 실행된다. 개발자는 애플리케이션의 다양한 상황에 구애받지 않고 UI 컴포넌트를 집중적으로 개발 할 수 있다.

지원하는 기능

  • UI 컴포넌트들을 카탈로그화하기
  • 컴포넌트 변화를 Stories로 저장하기
  • 핫 모듈 재 로딩과 같은 개발 툴 경험을 제공
  • 리액트를 포함한 다양한 뷰 레이어 지원

useRef


React만 가지고 거의 대부분의 프론트엔드 요구사항을 구현할 수 있었다.
DOM 지식이 필요없다고 생각할 수도 있다.
하지만 리엑트로 모든 개발 요구사항을 충족할 수는 없다.
아래와 같이 DOM 엘리먼트의 주소값을 활용해야 하는 경우 특히 그렇다

  • focus
  • text selection
  • media playback
  • 에니메이션 적용
  • j3.js, greensock 등 DOM 기반 라이브러리 활용

리엑트는 이런 예외적인 상황에서 useRef로 DOM Node, element, React 컴포넌트 주소값을 참조할 수 있다.

profile
FE_개발자_지망생

0개의 댓글