css의 성능 향상을 위해 탄생
특징
•
Automatic critical CSS
화면에 어떤 컴포넌트가 렌더링 되었는지 추적해서 해당하는 컴포넌트에 대한 스타일을 자동으로 삽입 → 최소한의 코드만으로 화면을 띄우기 가능
•
No class name bugs
스스로 유니크한 className 을 생성 → className 의 중복이나 오타로 인한 버그 감소
•
Easier deletion of CSS
컴포넌트를 더 이상 사용하지 않아 삭제할 경우 이에 대한 스타일 속성도 함께 삭제
•
Simple dynamic styling
React 의 props 나 전역 속성을 기반으로 컴포넌트에 스타일 속성을 부여하기 때문에 간단하고 직관적
•
Painless maintenance
컴포넌트에 스타일을 상속하는 속성을 찾아 다른 CSS 파일들을 검색하지 않아도 되기 때문에 코드의 크기가 커지더라도 유지보수가 어렵지 않습니다.
•
Automatic vendor prefixing
개별 컴포넌트마다 기존의 CSS 를 이용하여 스타일 속성을 정의하면 될 뿐입니다. 이외의 것들은 Styled Component 가 알아서 처리해 줍니다.
장점
•
css가 js파일에 같이 들어있어서 기능 파악이 쉽다. 클래스 이름 중복되지 않는다.
설치
# with npm
$ npm install --save styled-components
JavaScript
복사
package.json에 여러 버전의 styled component 설치되어 문제가 발생하는 것을 막는 코드 추가 권장
{
"resolutions": {
"styled-components": "^5"
}
}
JavaScript
복사
JavaScript에서 변수를 선언하듯이(혹은 React 에서 컴포넌트를 만들듯이) Button 을 만들고, tag 의 속성을 정의하고 (여기서는 a tag), back-ticks (``) 안에 기존 CSS 문법을 이용하여 스타일 속성을 정의
const Button = styled.a`
display: inline-block;
border-radius: 3px;
padding: 0.5rem 0;
margin: 0.5rem 1rem;
width: 11rem;
`;
JavaScript
복사
Adapting based on props & Extending Styles
스타일 속성을 지닌 컴포넌트를 정의할 때 함수를 전달하고, 그 안에서 props를 사용할 수 있음
// Button component
...
background: ${(props) => (props.primary ? "palevioletred" : "white")};
color: ${(props) => (props.primary ? "white" : "palevioletred")};
...
// App component
...
<Button>Normal</Button>
<Button primary>Primary</Button>
...
JavaScript
복사
또한 styled()로 컴포넌트를 감싸 상속이 가능하다.
변경하고 싶은 속성만 새로 정의해주면 기존 속성을 확장하여 사용가능
// 기존의 Button 컴포넌트에 Tomato 컴포넌트만을 위한 새로운 속성 추가
const Tomato = styled(Button)`
color: tomato;
border-color: tomato;
`;
JavaScript
복사
Passed props
컴포넌트에 props로 스타일 속성이 전달된다면 해당 컴포넌트는 props로 전달된 속성을 우선 적용한다.
import styled from "styled-components";
// Styled Component로 만들어진 Input 컴포넌트 입니다.
const Input = styled.input`
padding: 0.5em;
margin: 0.5em;
color: ${(props) => props.inputColor || "red"};
background: papayawhip;
border: none;
border-radius: 3px;
`;
export default function App() {
return (
<div>
{/* 아래 Input 컴포넌트는 styled component인 Input 컴포넌트에 지정된 inputColor(red)가 적용되었습니다. */}
<Input defaultValue="김코딩" type="text" />
{/* 아래 Input 컴포넌트는 props로 전달된 커스텀 inputColor(blue)가 적용되었습니다. */}
<Input defaultValue="박해커" type="text" inputColor="blue" />
</div>
);
}
JavaScript
복사
Styled Component 와 React Component
Styled Component 는 각 element 와 해당 element 에 대한 스타일 규칙의 조합입니다. 아래 예시 코드를 한번 살펴보겠습니다. <StyledCounter /> 컴포넌트에는 styled 라는 접두사가 추가되어 있습니다. 이것을 통해 React 컴포넌트인 <Counter/> 와 Styled Component 인 <StyledCounter /> 가 컴포넌트 이름으로 인해 서로 충돌하지 않고 React Developer Tools 및 Web Inspector 에서 쉽게 구분될 수 있습니다.
import React from 'react'
import styled from 'styled-components'
const StyledCounter = styled.div`
/* ... */
`const Paragraph = styled.p`
/* ... */
`const Button = styled.button`
/* ... */
`function Counter () {
const [count, setCount] = useState(0)
const increment = () => {
setCount(count + 1)
}
const decrement = () => {
setCount(count - 1)
}
return (
<StyledCounter>
<Paragraph>{count}</Paragraph>
<Button onClick={increment}>+</Button>
<Button onClick={decrement}>-</Button>
</StyledCounter>)
}
export default Counter;
Plain Text
복사
Styled Component의 정의는 render 메소드 밖에 정의하세요.
Styled Component 의 정의는 리턴문 밖에서 이루어져야 합니다. 만약 Styled Component 가 리턴문 안에서 정의되면 컴포넌트가 리렌더링 될 때마다 스타일 속성을 지닌 컴포넌트가 매번 새로 정의되고, 이는 렌더링 속도 저하에 큰 영향을 끼칩니다.
다음과 같이 Styled Component를 작성하세요.
/* Best Practice */
const StyledWrapper = styled.div`
/* ... */
`const Wrapper = ({ message }) => {
return <StyledWrapper>{message}</StyledWrapper>}
Plain Text
복사
다음은 안 좋은 예시입니다.
/* Bad Practice */
const Wrapper = ({ message }) => {
// WARNING: THIS IS VERY VERY BAD AND SLOW, DO NOT DO THIS!!!
const StyledWrapper = styled.div`
/* ... */
`return <StyledWrapper>{message}</StyledWrapper>}
Plain Text
복사