디자인과 개발 단계에서부터 재사용할 수 있는 UI 컴포넌트를 미리 디자인하고 개발 → 레고처럼 조립해 나갈 수 있는 부품 단위로 UI 컴포넌트를 만들어 나가는 개발 방법
예를 들어, 기존에 사용 중이던 버튼을 다른 화면에도 똑같이 사용해야 할 때, 새로 만들 필요 없이 애초에 재사용이 가능하도록 만들어둔다면 여러 프로젝트 혹은 여러 팀 간에 공유하여 부품을 조립하듯 효율적으로 재사용을 할 수 있다.
CSS 전처리기란, CSS가 구조적으로 작성될 수 있게 도움을 주는 도구로, 대표적으로 SASS 등이 있다.
허나, CSS 전처리기 자체만으로는 웹 서버가 인지하지 못하기 때문에 각 CSS 전처리기에 맞는 컴파일러를 사용해야 한다.
SASS와 같은 전처리기를 사용하면, 특정 속성의 값을 변수로 선언하여 필요한 곳에 선언된 변수를 적용할 수도 있고, 반복되는 코드를 한 번의 선언으로 여러 곳에서 재사용할 수도 있다.
허나, SASS가 CSS의 구조화를 해결해 주는 것의 장점보다 컴파일된 CSS의 용량이 어마어마하게 커지는 등의 문제가 더 많이 발생된다는 것을 발견하게 되었다.
위와 같은 CSS 전처리기의 문제를 보완하기 위해 BEM
, OOCSS
, SMACSS
와 같은 CSS 방법론이 대두되었다.
각각의 장단점이 있으나, 세 방법론 모두 같은 아래와 같은 지향점을 가지고 있다.
하지만 이러한 방법론들에서도 클래스명 선택자가 장황해지고, 이런 긴 클래스명 때문에 마크업이 불필요하게 커지며, 재사용하려고 할 때마다 모든 UI 컴포넌트를 명시적으로 확장해야만 하는 등의 문제점이 발생했다.
또한, 언어 로직 상에 진정한 캡슐화의 개념이 없어 클래스명에 의존해야 하는 문제도 있었다.
애플리케이션으로 개발 방향이 진화하면서 컴포넌트 단위의 개발은 캡슐화의 중요성을 불러왔다.
하지만 CSS는 컴포넌트 기반의 방식을 위해 만들어진 적이 한 번도 없었다. 결국 CSS 또한 컴포넌트 영역으로 불러들이기 위해 CSS-in-JS가 탄생해 이 문제를 해결하게 된다.
CSS-in-JS에는 대표적으로 Styled-Component가 있다.
Styled-Component는 기능적 혹은 상태를 가진 컴포넌트들로부터 UI를 완전히 분리해 사용할 수 있는 단순한 패턴을 제공한다.
CSS 코드를 다룰 때 다음과 같은 불편함을 느껴본 적이 있는가?
이런 불편함을 CSS를 컴포넌트화 시킴으로써 해결해주는 라이브러리가 있다. 바로 React 환경에서 사용 가능한 Styled Components 라는 라이브러리다.
Styled Components는 CSS-in-JS 라는 개념이 대두되면서 나온 라이브러리로, 기존에 HTML, CSS, JS 파일로 쪼개서 개발하던 방법에서 React 등의 라이브러리의 등장으로 컴포넌트 단위 개발이 주류가 되었지만, CSS는 그렇지 못했다는 점에서 출발한 개념이다.
CSS-in-JS 라이브러리를 사용하면 CSS도 쉽게 Javascript 안에 넣어줄 수 있으므로, HTML + JS + CSS까지 묶어서 하나의 JS파일 안에서 컴포넌트 단위로 개발할 수 있게 된다. 이런 CSS-in-JS 라이브러리 중에서 현재 가장 인기 있는 라이브러리가 바로 Styled Components 이다.
npm install --save styled-components
Styled Components는 package.json에 다음 코드를 추가하도록 권장하고 있다. 아래의 코드를 추가하면 여러 버전의 Styled Components가 설치되어 발생하는 문제를 줄여준다.
{
"resolutions": {
"styled-components": "^5"
}
}
import styled from "styled-components"
여기까지 했다면, Styled-Component를 사용할 준비가 완료된 것이다.컴포넌트 만들기
import styled from "styled-components";
// 컴포넌트를 선언한 후 styled.태그종류를 할당하고, 백틱 안에 기존에 CSS를 작성하던 문법과 똑같이 스타일 속성을 작성
const BlueButton = styled.button`
background-color: blue;
color: white;
`;
export default function App() {
// React 컴포넌트를 사용하듯이 사용하면 된다
return <BlueButton>Blue Button</BlueButton>;
}
컴포넌트를 재활용해 새로운 컴포넌트 만들기
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 활용
Styled Component로 만든 컴포넌트도 React 컴포넌트처럼 props를 내려줄 수 있다. 내려준 props 값에 따라서 컴포넌트를 렌더링하는 것도 가능하다.
const 컴포넌트이름 = styled.태그종류`
CSS속성: ${ (props) => {함수 코드} }
`;
조건부 렌더링하기
const Button1 = styled.button`
background: ${(props) => (props.skyblue ? "skyblue" : "white")};
`;
export default function App() {
return (
<>
<Button1>Button1</Button1> // 배경 색 white로 지정됨
<Button1 skyblue>Button1</Button1> // 배경 색 skyblue로 지정됨
</>
);
}
Props 값으로 렌더링하기
//받아온 prop 값을 그대로 이용해 렌더링할 수 있음
const Button1 = styled.button`
background: ${(props) => (props.color ? props.color : "white")};
`;
//삼항연산자가 아닌 JS 코드라면 무엇이든 사용 가능. 아래와 같은 형식으로도 활용할 수 있음
const Button2 = styled.button`
background: ${(props) => props.color || "white"};
`;
export default function App() {
return (
<>
<GlobalStyle />
<Button1>Button1</Button1>
<Button1 color="orange">Button1</Button1>
<Button1 color="tomato">Button1</Button1>
<br />
<Button2>Button2</Button2>
<Button2 color="pink">Button2</Button2>
<Button2 color="turquoise">Button2</Button2>
</>
);
}
전역 스타일 설정하기
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
button {
padding : 5px;
margin : 2px;
border-radius : 5px;
}
`
<GlobalStyle>
컴포넌트를 최상위 컴포넌트에서 사용해주면 전역에 <GlobalStyle>
컴포넌트의 스타일이 적용된다.function App() {
return (
<>
<GlobalStyle />
<Button>전역 스타일 적용하기</Button>
</>
);
}
style.css 파일에 적용되어 있는 스타일을 styled Components의 컴포넌트로 바꿔보자.