💅

Styled Component

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
복사