40일차 컴포넌트 단위로 개발하기
2021. 09. 13 월요일
1. Today's Key Points!🔑
- 컴포넌트 단위로 개발하기
- CSS in JS
- useRef
2. 정리해보자!🧹
👉🏻컴포넌트 단위로 개발하기
부품 단위로 UI 컴포넌트를 만들어 나가는 개발을 통해서 각 페이지마다 같은 역할을 하는 것이 필요할 때 같은 UI 컴포넌트를 공유하면 편리하게 페이지를 구성할 수 있다. 그래서 디자인과 개발 단계에서부터 재사용할 수 있는 UI 컴포넌트를 미리 디자인하고 개발하면 효율적으로 페이지를 구성할 수 있을 것이다. 이러한 개발 방법이 Component Driven Development(CDD)라고 한다.
CDD가 트렌드로 자리잡게 되면서 이를 지원하는 도구 중 하나인 Component Explorer가 등장했는데 그 중 하나가 Storybook이다.
Storybook은 CDD를 하기 위한 도구이다. 각각의 컴포넌트들을 따로 볼 수 있게 구성해줘서 한 번에 하나의 컴포넌트에서 작업할 수 있다. Storybook의 특징은 이러하다.
- 애플리캐이션 탐색할 필요 없이 전체 UI를 한눈에 보고 개발할 수 있다.
- 재사용성 확대
- 컴포넌트 문서화
- 자동으로 컴포넌트를 시각화하여 시뮬레이션할 수 있는 다양한 테스트 상태 확인가능
- 애플리케이션 의존성 고려하지 않아도 됨.
- 이로인한 버그 사전 방지, 테스트 및 개발 속도 향상
주요 기능은 이러하다.
- UI 컴포넌트들을 카탈로그 화하기
- 컴포넌트 변화를 Stories로 저장하기
- 핫 모듈 재 로딩과 같은 개발 툴 경험을 제공하기
- 리액트를 포함한 다양한 뷰 레이어 지원하기
👉🏻CSS in JS
구조화된 CSS가 필요하게 된 이유 : 프로젝트의 규모와 복잡도가 커졌기 때문. 모바일이나 태블릿을 비롯한 다양한 디바이스들의 등장으로 웹사이트가 다양한 디스플레이를 커버해야 하기 때문.
이러한 문제점들을 해결하기 위해 나온 개념. 1) CSS 전처리기(CSS Preprocesseor). CSS가 구조적으로 작성될 수 있게 도움을 주는 도구. 전처리기 중에서 가장 유명한 SASS(Syntactically Awesome Style Sheets)는 CSS를 확장해 주는 스크립팅 언어이다. 자바스크립트처럼 특정 속성(ex. color, margin, width 등)의 값(ex. #ffffff, 25rem, 100px 등)을 변수로 선언해서 반복되는 코드를 한번의 선언으로 여러곳에서 재사용할 수 있도록 해주는 등의 기능을 가졌다. SCSS 코드를 읽어서 전처리한 다음 컴파일해서 전역 CSS 번들 파일을 만들어주는 전처리기의 역할을 한다.
//SASS 변수 사용 예제
//반복되는 CSS 코드가 있다면 변수를 활용해서 재사용이 가능.
//변수를 선언할 때는 $ 기호를 활용.
$base-color: rgba(198, 83, 140, 0.88)
.alert {
border: 1px solid $base-color
}
.button {
color: $base-color
}
하지만 구조화를 해결해 주는 것의 장점보다 문제점들이 더 많다는 것이 밝혀진다. 이러한 CSS 전처리기 문제를 보완하기 위해 BEM, OOCSS, SMACSS 같은 2) CSS 방법론이 대두되었다. 이 방법론의 공통 지향점은 코드의 재사용, 코드의 간결화, 코드의 확장성, 코드의 예측성이다. 대표적인 CSS 방법론으로 BEM이 있다.
BEM이란 Block, Element, Modifier로 구분해서 클래스명을 작성하는 방법이고, Block, Element, Modifier 각각은 --와 __로 구분한다.
//Block, Element, Modifier로 구분해서 클래스명을 작성하는 방법
//Block Element Modifier
.header__navigation--navi-text {
color: red;
}
하지만 이러한 방법론들에서도 문제점이 발생한다. 클래스명 선택자가 장황해지고, 긴 클래스명 때문에 마크업이 불필요하게 커지고, 재사용하려고 할 때마다 모든 UI 컴포넌트를 명시적으로 확장해야만 했다.
이러한 문제를 해결해줄 수 있는 방법이 CSS를 컴포넌트 기반으로 작성하는 것이다. 이러한 3) CSS-in-JS에는 대표적으로 Styled-Component가 있다. Styled-Component는 기능적(Functional) 혹은 상태를 가진 컴포넌트들로부터 UI를 완전 분리해 사용할 수 있는 아주 단순한 패턴을 제공한다.
그럼 Styled-Component를 어떻게 사용하는지 알아보자.
Styled-Component는 React의 컴포넌트 기반 개발 환경에서 스타일링을 위한 CSS의 성능을 향상시켜준다. 기존 CSS 문법으로 스타일 속성이 추가된 React 컴포넌트를 만들 수 있다. 예를 들어 Styled-Component를 이용해서 어플리케이션 내에 Button을 하나 만든다면 아래와 같은 코드로 만들어 줄 수 있다.
const Button = styled.a`
display: inline-block;
border-radius: 3px;
padding: 0.5rem 0;
margin: 0.5rem 1rem;
width: 11rem;
`;
JavaScript에서 변수 선언하듯이 Button을 만들고, tag 속성을 정의하고, back-ticks(``)안에 기존 CSS 문법을 이용해서 스타일 속성을 정의해준다.
Styled Component 특징
- Automatic critical CSS : Styled Component는 화면에 어떤 컴포넌트가 렌더링 되었는지 추적해서 해당하는 컴포넌트에 대한 스타일을 자동으로 삽입한다.
- No class name bugs : Styled Component는 스스로 유니크한 className을 생성한다.
- Easier deletion of CSS : Styled Component 는 모든 스타일 속성이 특정 컴포넌트와 연결되어 있기 때문에 만약 컴포넌트를 더 이상 사용하지 않아 삭제할 경우 이에 대한 스타일 속성도 함께 삭제된다.
- Simple dynamic styling : className을 일일이 수동으로 관리할 필요 없이 React의 props나 전역 속성을 기반으로 컴포넌트에 스타일 속성을 부여하기 때문에 간단하고 직관적이다.
- Painless maintenance : 컴포넌트에 스타일을 상속하는 속성을 찾아 다른 CSS 파일들을 검색하지 않아도 되기 때문에 코드의 크기가 커지더라도 유지보수가 어렵지 않다.
- Automatic vendor prefixing : 개별 컴포넌트마다 기존의 CSS를 이용하여 스타일 속성을 정의하면 된다. 이외의 것들은 Styled Component가 알아서 처리해 준다.
Styled Component 설치방법. 터미널에 아래의 명령어 입력
# with npm
$ npm install --save styled-components
# with yarn
$ yarn add styled-components
예제. 스타일 속성을 지닌 컴포넌트를 정의할 때에 함수를 전달하고, 그 함수 안에서 props 를 사용할 수도 있다. <Button> 컴포넌트의 background 와 color 속성은 primary 라는 props 의 전달 여부에 따라 컬러값을 정의하고 있다.
// Button component
...
background: ${(props) => (props.primary ? "palevioletred" : "white")};
color: ${(props) => (props.primary ? "white" : "palevioletred")};
...
// App component
...
<Button>Normal</Button>
<Button primary>Primary</Button>
...
또한 같은 스타일 속성을 지닌 여러개의 컴포넌트들 중 몇 개의 컴포넌트에는 약간의 변화를 주고 싶은 경우도 있을 것이다. 이때에는 상속받고자 하는 스타일 속성을 지닌 컴포넌트를 styled() 로 감싼 뒤, 변경하고 싶은 속성만 새로 정의해 주면 기존 속성을 확장하여 사용할 수 있다.
// 기존의 Button 컴포넌트에 Tomato 컴포넌트만을 위한 새로운 속성 추가
const Tomato = styled(Button)`
color: tomato;
border-color: tomato;
`;
👉🏻useRef
React에서 querySelector로 주소에 접근하면 안된다. 왜냐하면 React는 DOM에 직접 접근하는 것을 가정하지 않고, 내부 작업을 하기때문이다. 근데 DOM에 접근해야 하는 경우가 있다. DOM으로만 작성된 라이브러리를 쓰는 경우, React Element가 아니라 HTML 형식으로 작성된 경우에는 DOM에 접근을 해야할 것이다. 이때 접근을 가능하게 해주는 것이 useRef이다. 아래 예시 코드처럼 작성하면 주소값을 활용할 수 있다.
const 주소값을_담는_그릇 = useRef(참조자료형)
// 이제 주소값을_담는_그릇 변수에 어떤 주소값이든 담을 수 있다.
return (
<div>
<input ref={주소값을_담는_그릇} type="text" />
{/* React에서 사용 가능한 ref라는 속성에 주소값을_담는_그릇을 값으로 할당하면*/}
{/* 주소값을_담는_그릇 변수에는 input DOM 엘리먼트의 주소가 담긴다. */}
{/* 향후 다른 컴포넌트에서 input DOM 엘리먼트를 활용할 수 있다. */}
</div>
);
이 주소값은 컴포넌트가 re-render 되더라도 바뀌지 않는다. 이 특성을 활용하여 아래의 제한된 상황에서 useRef를 활용할 수 있다.
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
'코드스테이츠 수강 TIL > Section 2' 카테고리의 다른 글
42일차 React Custom Component2 (0) | 2021.09.16 |
---|---|
41일차 React Custom Component (0) | 2021.09.16 |
39일차 StatesAirline Server (0) | 2021.09.11 |
38일차 Refactor Express (0) | 2021.09.11 |
37일차 Mini Node Server (0) | 2021.09.10 |