Css in JS 라는 기술이며, Styled-components 는 JS 안에 CSS를 작성하는 기술을 사용하는 라이브러리이다.
styled-components를 사용하기전에, Tagged Template Literal이라는 문법에 대해 알아보자.
Template Literal은 많이 사용했으니 익숙하다. 문자열 조합을 쉽게 할수 있게 해주는 문법이다.
const name ='react';
const message = `hello ${name}`;
console.log(message);
// "hello react"
그럼 만약에 ${}안에 일반 문자열/숫자가 아니라 객체나 함수를 집어넣으면 어떻게 될까?
const object = {a:1 };
const text = `${object}`
console.log(text);
// "[object Object]"
const fn = () => true
const msg = `${fn}`;
console.log(msg);
// "() => true"
객체는 원하는 값 대신에 type값이 나와버리고, 함수는 ()=>true 라는 구문이 나와버린다.
자신이 Template Literal을 사용하면서도, 그 내부에 넣은 자바스크립트 값을 조회하고 싶을 때 사용하는 것이 바로 Tagged Template Literal문법이다.
const red = '빨간색';
const blue = '파란색';
function favoriteColors(texts, ...values) {
console.log(texts);
console.log(values);
}
favoriteColors`제가 좋아하는 색은 ${red}과 ${blue}입니다.`
함수 파라미터쪽에서는 파라미터의 rest 문법이 사용되었고, 입력한 문자열이 분해되어서, 넣어준 텍스트와 ${}를 통해 넣어준 자바스크립트 값을 따로따로 볼수 있다. 이렇게 분리된 값들을 사용해서 일련의 작업을 수행할 수 있다.
const red = '빨간색';
const blue = '파란색';
function favoriteColors(texts, ...values) {
return texts.reduce((result, text, i) => `${result}${text}${values[i] ? `<b>${values[i]}</b>` : ''}`, '');
}
favoriteColors`제가 좋아하는 색은 ${red}과 ${blue}입니다.`
// 제가 좋아하는 색은 <b>빨간색</b>과 <b>파란색</b>입니다.
함수에서 입력받은 텍스트를 text와 values 값으로 나누고 해당 조건에 맞게 reduce함수를 거쳐서 texts를 리턴한다. 그냥 이런 문법이 있다는것만 알아두자.
새로운 프로젝트를 만들고 , styled-components를 설치한다.
npx create-react-app styling-with-styled-components
cd tyling-with-styled-components
yarn add styled-components
import React from 'react';
import styled from 'styled-components';
const Circle = styled.div`
width: 5rem;
height: 5rem;
background: black;
border-radius: 50%;
`;
function App() {
return <Circle/>;
}
export default App;
이렇게 styled-components를 사용하면 이렇게 스타일을 입력함과 동시에 스타일을 가진 컴포넌트를 생성할 수 있다.
div를 스타일링 하고싶으면 styled.div를 input을 스타일링 하고싶으면 styled.input으로 사용한다.
물론 해당 컴포넌트에 속성추가도 가능하다.
import React from 'react';
import styled from 'styled-components';
const Circle = styled.div`
margin: 10px;
width: 5rem;
height: 5rem;
background: ${props => props.color || 'black'}; //props에서 color값을 사용하거나, 없으면 기본값으로 black을 지정한다.
border-radius: 50%;
`;
function App() {
return <Circle color='blue'/>;
}
export default App;
이번에는 huge라는 props값을 추가해서 속성이 지정되면 크기가 더 커지는 방식으로 만들어보자
크기 비교를 위해서 Circle 컴퍼넌트 하나를 추가했다.
const Circle = styled.div`
margin: 10px;
width: 5rem;
height: 5rem;
background: ${props => props.color || 'black'};
border-radius: 50%;
${props => props.huge &&
`
width: 10rem;
height: 10rem;
`}
`;
function App() {
return(
<>
<Circle color='blue'/>
<Circle color='blue' huge/>
</>
)
}
성공적으로 크기가 커진 모습이지만, huge에 대한 조건 스타일링을 template Literal로 지정을 하면 외부에서 다른 props의 값을 읽어올 수 없다. 위에서 설명했던 Tagged Template Literal로 사용해야 외부에서 props를 읽을 수 있다.
그렇게 하려면 {css}를 inport 해서 가져온뒤, huge조건문을 아래와 같이 수정한다.
import styled, {css} from 'styled-components';
const Circle = styled.div`
margin: 10px;
width: 5rem;
height: 5rem;
background: ${props => props.color || 'black'};
border-radius: 50%;
${props =>
props.huge &&
css`
width: 10rem;
height: 10rem;
`}
`;
이런 방식으로 수정을 하면 나중에 외부에서 props를 추가적으로 읽어올 수 있게된다.