개발자들은 작은 단위의 컴포넌트들을 개발하고,
이러한 컴포넌트들을 조합하여 더 큰 기능을 가진 애플리케이션을 구성하는 것이다.
이렇게 구성된 애플리케이션은 재사용성과 유지보수성이 높아지며, 테스트와 개발이 용이해진다.
CDD를 이용하면, 개발자들은 디자이너와 협업하여 컴포넌트에 대한 설계, 스타일, 상태, 인터랙션 등을 정의하고,
이를 이용하여 UI 라이브러리나 디자인 시스템을 만들 수 있다.
CDD는 다양한 형태의 컴포넌트 라이브러리를 이용하여 개발할 수 있다.
예를 들어 React를 이용하여 컴포넌트를 개발하고 Storybook을 이용하여,
컴포넌트의 UI 및 상태를 확인하고 테스트할 수 있다.
이러한 CDD 방법론은 개발자와 디자이너, 프로덕트 매니저 등의 역할을 분리하여 각자의 역할에 집중할 수 있도록 해주고, 협업을 원활하게 할 수 있도록 도와줍니다. 또한, 재사용성이 높은 UI 라이브러리나 디자인 시스템을 만들어 관리할 수 있으므로, 프로젝트의 일관성과 생산성을 높일 수 있습니다.
POST PC 시대가 도래하고, 사용할 수 있는 다양한 하드웨어 기기가 발전했다.
이에 따라 개발자들의 CSS 작성 방식도 꾸준히 진화해왔다.
PC, 모바일, 태블릿 등 다양한 디바이스에서 웹 사이트를 사용하는데,
디바이스의 디스플레이 크기가 제각각 다르므로,CSS는 더욱 복잡해졌다.
CSS 작업을 더욱 효율적으로 하기 위해 구조화된 CSS 필요성이 대두되었다.
CSS 전처리기 개념이 등장했다.
CSS 전처리기는 CSS의 기능을 확장한 스크립트 언어이며, CSS 코드 작성을 효율적으로 하기 위한 도구 중 하나다.
전처리기를 사용하면, 변수, 함수, 조건문, 반복문 등과 같은 기능을 CSS에서 사용할 수 있다.
이를 통해 코드의 재사용성을 높이고, 유지보수성을 향상시킬 수 있다.
대표적인 CSS 전처리기로는 Sass, Less, Stylus 등이 있다.
이들은 모두 변수, mixin, extend 등의 기능을 제공하며,
CSS 작업을 보다 구조화된 방식으로 처리할 수 있도록 도와준다.
또한 이들 전처리기는 브라우저에서 지원하지 않는 기능을 사용할 수 있게 해주기도 한다.
전처리기를 사용함으로써 작업 속도, 코드의 가독성, 유지보수성을 높일 수 있지만, 동시에 여러 단점도 발생되었다.
SASS가 CSS의 구조화를 도입하면서 생긴 문제를 예로 들어보자.
어쨌든, 다양한 방법론의 공통 지향점은 아래와 같다.
이러한 문제들을 해결하기 위해, CSS-in-JS 개념이 만들어졌다.
CSS를 컴포넌트 영역에서 스타일링하는 것이다.
대표적으로 Styled-Component가 있다.
Styled-Component는 기능적 혹은 상태를 가진 컴포넌트들로부터 UI를 완전히 분리해,
사용할 수 있는 아주 단순한 패턴을 제공한다.
CSS-in-JS는 컴포넌트 단위로 CSS 스타일링을 하는 개념으로,
컴포넌트를 렌더링할 때마다 해당 컴포넌트에 필요한 스타일이 동적으로 생성된다.
이렇게 하면 컴포넌트 단위로 스타일링을 하기 때문에,
전역 스타일 충돌과 같은 문제를 해결할 수 있으며, 재사용성과 유지보수성이 향상된다.
React(HTML+JS) + CSS
=> React + styled-component = React에서 한꺼번에 HTML+CSS+JS 를 작성한다.
Styled-Component는 React 기반의 CSS-in-JS 라이브러리 중 하나로,
JSX 안에 스타일링 정보를 포함시키는 방식으로 동작한다.
터미널에 Styled Components 라이브러리 설치
$ npm install --save styled-components
$ yarn add styled-components
Styled Components는 package.json에 다음 코드를 추가하도록 권장한다.
아래의 코드를 추가하면 여러 버전의 Styled Components가 설치되어 발생하는 문제를 줄여줍니다.
{
"resolutions": {
"styled-components": "^5"
}
}
import styled from "styled-components"
Styled Components는 ES6의 Templete Literals 문법을 사용한다.
즉, 따옴표가 아닌 백틱을 사용한다.
const 컴포넌트 이름 = styled.태그 css 속성 1 : 속성값; css 속성 2 : 속성값;
태그 끝에부터 백틱을 사용해서 css 속성을 감싸주는 것을 잊지 말자.
예시
const OpenButton = styled.button`
background-color : green;
color : white;
`;
위에서 만든 OpenButton으로 새로운 버튼을 만들 수 있다.
OpenButton과 똑같은 컴포넌트를 재활용 하는 것인데,
이 컴포넌트에 새로운 CSS를 스타일링 할 수 있다.
const NewOpenButton = styled(OpenButton)`
background-color : green;
color : white;
`;
자세히보면, styled 뒤에, dot(.)이 오는게 아니라,
소괄호안에 컴포넌트를 입력해주는 문법을 볼 수 있다.
Styled Component로 만든 컴포넌트도 React 컴포넌트처럼 props를 내려줄 수 있다.
내려준 props 값에 따라서 컴포넌트를 렌더링 하는 것도 가능하다.
const 컴포넌트 = styled.태그`
css 속성 : ${ (props) => 함수 코드 }
`;
Styled Components는 템플릿 리터럴 문법(${ })을 사용하여 JavaScript 코드를 사용할 수 있다.
props를 받아오려면 props를 인자로 받는 함수를 만들어 사용하면 된다.
const Button = styled.button`
background-color: ${(props) => props.green ? "green" : "white" }
`;
삼항 연산자를 사용해, Button 컴포넌트에 green이라는 props가 있으면, 배경색을 green으로, 없으면 white로 지정하는 코드이다.
만약 아래와 같이 컴포넌트를 만들면, 녹색 버튼과 흰색 버튼이 렌더링 될 것이다.
<Button green>Button1</Button> => 녹색 버튼
<Button>Button1</Button> => 흰색 버튼
props의 값을 색으로 나타낸 예시 2가지
const Button1 = styled.button`
background: ${(props) => (props.color ? props.color : "white")};
`;
// props.color가 있으면, props.color 리턴, 없으면 흰색 리턴
const Button2 = styled.button`
background: ${(props) => props.color || "white"};
`;
// props.color 또는 흰색 리턴
꼭 삼항 연산자만 사용해야 하는 것은 아니다.
JavaScript 코드라면 무엇이든 사용할 수 있으므로 원하는 값을 사용할 수 있도록,
함수 코드를 만들어서 사용하면 된다.
때론, 컴포넌트에 일일이 스타일을 해주는 것은 번거로울 수도 있다.
전역 스타일링을 할 수 있는 방법이 있다.
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
button {
padding : 10px;
margin : 5px;
border-radius : 15px;
}
`
function App() {
return (
<>
<GlobalStyle />
<Button>전역 스타일 적용</Button>
</>
);
}
React 컴포넌트와 CSS를 결합하여, 이를 하나의 단위로 다룰 수 있다.
스타일 정보와 컴포넌트 로직이 함께 작성되므로, 코드의 가독성과 유지보수성이 향상된다.
CSS 파일을 작성할 필요가 없으며, CSS의 모든 기능을 JavaScript 코드 안에서 사용할 수 있다.
이러한 방식의 CSS-in-JS를 사용함으로써, 애플리케이션의 성능도 개선된다.
또한, Styled Components는 CSS의 캡슐화 기능을 지원하기 때문에,
전역 스타일 충돌을 방지하고, 컴포넌트 내부 스타일의 영향력이 컴포넌트 외부로 노출되는 것을 막아준다.
초기 학습 곡선이 높다.
기존 CSS를 작성하는 방식과는 다른 방식이기 때문에 처음에는 적응이 필요하다.
성능에 대한 이슈가 있을 수 있다.
styled component는 컴포넌트 단위로 스타일을 생성하기 때문에 렌더링이 느려질 수 있다.
이를 해결하기 위해 CSS-in-JS 라이브러리 중에서는 일부가 서버사이드 렌더링에 최적화된 솔루션을 제공하기도 한다.
재사용성과 관리의 어려움.
스타일을 컴포넌트와 함께 작성하다 보면, 다른 컴포넌트에서 재사용하기가 어려울 수 있다.
또한 스타일이 분산되어 있어 유지보수가 어려울 수 있다.
이를 해결하기 위해 컴포넌트 라이브러리와 같은 방법을 사용할 수 있다.
서버사이드 렌더링이 어려울 수 있다.
styled component는 기본적으로 클라이언트에서 동작하기 때문에 서버사이드 렌더링을 할 때 조금 더 복잡한 설정이 필요할 수 있다.
이를 해결하기 위해 styled-components에서는 서버사이드 렌더링을 위한 API를 제공한다.
Styled Component는 CSS를 컴포넌트에서 관리할 수 있어 유지보수성이 좋아지고 재사용성도 증가하는 장점이 있지만, 초기 학습 곡선이 높고, 성능과 서버사이드 렌더링 등의 이슈도 고려해야 한다.
UI 개발 도구 - 컴포넌트 시각화 & 문서화
React는 가상 DOM을 사용한다.
가상 DOM을 거쳐서 진짜 DOM을 바꾸는게 react의 기본 작동 방식이다.
진짜 DOM을 직접 건드리는 것은 react의 기본 작동 방식에 어긋나는 방식이다.
하지만, DOM을 직접 건드리는 것이 더 좋은 상황이 있다.
예를 들어, DOM 객체 주소가 필요한 상황이다.
focus, media playback
그 때 사용하려고 useRef 메서드를 만든 것이다.
useRef를 쓸 때, usestate로 상태관리를 하지 않는다.
(중요)리액트에서 상태가 변하면 리렌더링 된다.
예제를 보자.
리렌더링이 되면, 입력창에 작성한 내용이 사라질텐데?
그럼 작성한 내용이 사라지지 않게 하려면?
useState를 쓰는 방식
상태를 4개를 관리해야 한다.
focus, input 1, input2, input3, input4
useRef를 쓰는 방식
상태가 바뀐게 아니기 때문에, 내용이 남아있게 된다.
예제 2번 동영상
상태로 관리할 때,
Play, pause 버튼이 있다.
isplaying 일 때, 재생 상태로 하자.
play, pause를 누를 때면, 리렌더링이 된다.
그럼 중간에 영상을 멈추지 못하게 된다.
따라서, 상태 관리로 쓸 수 없고, useRef를 이용해서 진짜 DOM을 조작해야 한다.
true false 왔다갔다 할 때는, !를 사용하면 좋다.
Styled-Components 사용하면,
따로 클래스명을 지정하지 않아도 된다.
하지만, 개발자 도구에서 element를 확인해보면, div class에 이상한 클래스명이 생긴다.
=> 어떤 클래스인지 알아보기 어려우니, 클래스 옆에 id를 지정해서, 표시한다. 이 과정은 좀 번거로워 보인다.
새로 알게 된 사실
z-index
Background-color: rgba(0, 0, 0, 0)
16진수보다 이렇게 쓰면 더 편하다.
Position: fixed;
=> 내가 페이지 스크롤을 올리거나 내려도, 계속 가운데에 고정된다.
left: 0; right:0; top:0; bottom:0;
=> 양옆 위 아래에 붙으라고 명령했기 때문에, 화면에 꽉 찬다.
Flex-direction: column
인간은 어떻게 하면 더 편하게 할 수 있을까를 고민한다.
하지만, 편하다고 다 좋은 것은 아닌 것 같다는 직감이 든다.
편한 만큼 그에 상응하는 댓가가 반드시 있을 거라는 생각이 든다.