styled-components

박종한·2020년 2월 5일
0

React

목록 보기
8/17

styled-components?

.js파일에 css를 넣을 수 있도록 해주는 편리한 라이브러리
(CSS-in-JS 라이브러리 라고 부른다고 함)

yarn add styled-components

로 다운받을 수 있음

usage

import styled from 'styled-components';

다음처럼 .js파일에서 import

const variable = styled.div``;

사용법은 위와 같음. 변수 안에 집어넣는데, .div부분은 .input, .button등등으로 바꿀 수 있음
그리고 안에는 css코드를 삽입

const variable = styled.div`
	width: 100px;
	height: 100px;
	background: red;
	border-radius: 4px;
`;

보통 css처럼 사용하면 되는데, 이를 렌더링 할때도 <variable>태그를 써서, 안에 내용물들을 넣어 줄 수 있음
즉, 원래는 <div className="variable"/>이런식으로 정의하고 다른 .css.scss같은 파일에서 그걸 꾸미는 코드를 넣어줘야 하는데, 그럴 필요없이 .js파일로만 해당 div를 꾸며줄 수 있다는 얘기

Tagged Template Literal

우리가 알고 있는

`hihihi ${name}`

이런 류는 템플릿 리터럴 이라고 부르긴 하지만, 앞에 tagged라는게 들어가지 않는다.
템플릿 리터럴은 그냥 문자열 안에 특정 자바스크립트 값을 넣어 문자열을 만드는 것 (백틱'`'을 사용)

일반 템플릿 리터럴의 경우는 문제가 객체나, 함수를 출력하려고 할때인데, 객체의 경우는 단순히 [Object] 이런식으로 출력이 되고, 함수는 함수의 내용물이 그냥 출력된다 예를 들어

const hi = () => {}

라는 함수를 ${hi}로 출력해보면, () => {}가 출력된다.

반면 Tagged Template Literal은 다음과 같이 쓸 수 있다.

const coffee = '카페라떼'
const price = '3000'

function favoriteCoffee(texts, ...values){
  console.log(texts);
  console.log(values);
}

favoriteCoffee`제가 제일 좋아하는 커피는 ${coffee}이고, 가격은 ${price}입니다.`;


실제로 출력해보면 위와 같은데, 한마디로, ()로 함수를 호출하는게 아니라 ``로 호출하는데 그 안의 내용물들이 매개변수처럼 보이지만, 값이 두 분류로 토막나는 과정이 더해진 다음 함수 호출이 이뤄진다. 문자열과 ${}를 사용한게 각각 따로 호출된다.

이걸 잘 활용해보면 ``로 함수를 호출할때 매개변수를 reduce를 통해서 각각의 ${}에 태그를 더 넣어줄 수 있다. 예를 들면 b(bold 태그) 라든가

그럼 styled-components에선 이걸 어떻게 쓸까?

const variable = styled.div`
	width: 100px;
	height: 100px;
	background: red;
	border-radius: 4px;
`;

위 처럼, 단순히 외부의 값을 아무것도 읽지 않는 경우라면 모르겠지만, 호출하는 쪽에서
<variable color="white"></variable>
같이 props를 넣어주게 되면, 이를 읽어들일 필요가 있다. 그래서 Tagged Template Literal이 쓰이는 것이다.

아래 추가 설명

props

const Text = styled.div`
  flex: 1;
  font-size: 21px;
  color: #495057;
  ${props =>
    props.done &&
    css`
      color: #ced4da;
    `};
`;

다음 코드에서는 못 보던 코드가 생겨서 조금 당황스러운 것이 있음
바로 ${props} 하지만 해석은 실로 단순함

<Text done={done}>{text}</Text>

건네주는 쪽의 코드가 위와 같은데, 보면 done={done}으로 props를 넘겨주고 있음
styled-components에서는 props${props}로 받고, 안의 내용물들을 사용하고 싶으면 위의 경우처럼 ${props => props.something} 이런식으로 사용하면 됨 => 이것이 바로 Tagged Template Literal 사용 이유

어떻게 사용할 수 있는 거냐 궁금한데, 예시를 가져와 보겠다.

function example(texts, ...fns){
  const props = {
    title: '어렵다.',
    body: '어려워용'
  }
  return texts.reduce((result, text, i) => `$(result)${text}${fns[i] ? fns[i](props) : ''}`, '');
}

//호출 쪽
example`
	title!: ${props => props.title}
	content!: ${props => props.body}
`

/*결과
    title!: 어렵다.
    content!: 어려워용
*/

이번엔 TTL(태그 리터럴 템플릿을 그냥 줄여서 이렇게 부르겠다 네트워크에서의 Time To Live 아님..)에 함수를 넣어서 호출을 하는 모습을 볼 수 있는데, 함수에선 이 함수를 매개변수로 받아 ...fns로 만들어준다.

그리고 reduce함수를 통해 그 값을 조작할 수가 있는데, props에 있는 걸 fns의 파라미터로 넣어서 결과물을 만들어낸다.

따라서 Styled-Components에서 props를 받아들여오면 그걸 이용해서 어떤 원리를 통해 CSS코드를 실행시키는 것이다.

css``;

아까 보던 코드를 다시 봐보자.

```javascript
const Text = styled.div`
  flex: 1;
  font-size: 21px;
  color: #495057;
  ${props =>
    props.done &&
    css` // => 이건 뭐지..?
      color: #ced4da;
    `};
`;

독특한 코드가 있는데 바로 css``이다.

이 코드는 ${}안에서도 TTL코드를 적어서 적용할 수 있도록 해준다. 만약 css를 적지 않는다면, TTL이 아니라 그냥 템플릿 리터럴이 된다. 즉 ``안에는 ${}를 적어도 styled에게 TTL처럼 전달이 되지 않는다.

  ${props =>
    props.done &&
    css`
      color: #ced4da;
    `};

이 코드의 경우 props에서 가져온 donetrue이면 뒤의 css코드에 의해서 text의 색상이 #ced4da로 바뀜 하지만 만약 donefalse라면 색은 기본값인 #495057다.

css를 사용하려면,

import { css } from styled-components;

가 필요하다.

자세한 설명은
https://styled-components.com/docs/api#css
를 참고하자.

Polished 라이브러리

styled-components안에서 sass에서 사용하는 darken, lighten같은 기능들을 사용할 수 있도록 해주는 라이브러리

yarn add polished

로 가져오고 styled-components의 TTL 태그안에서는
${lighten(0.1, '색깔')} 이런식으로 쓸 수 있다.

ThemeProvider

App.js에서 {ThemeProvider}를 import하면, App의 자식 컴포넌트들도 App에서 선언한 Theme를 가져다 사용할 수 있다. 즉 색상들을 ThemeProvider를 통해 제공하고 자식 컴포넌트들은 굳이 자신의 파일안에 선언하지 않아도 부모 컴포넌트에서 제공하는 색상들을 쓸 수 있다.

const palette = {
  blue: '#228be6',
  lime: '#d8f5a2',
  pink: '#f06595',
};

다음과 같이 정의된 색상을

    <ThemeProvider theme={{ palette }}>
      <AppBlock>
        <div className="buttons">
          <Button>BUTTON</Button>
          <Button color="pink">BUTTON</Button>
          <Button color="lime">BUTTON</Button>
        </div>
      </AppBlock>
    </ThemeProvider>

이런식으로 ThemeProvider태그의 theme prop을 통해 설정해두면,

  ${({ theme, color }) => {
    const selected = theme.palette[color];
    return css`
      background: ${selected};
      &:hover {
        background: ${lighten(0.1, selected)};
      }
      &:active {
        background: ${darken(0.1, selected)};
      }
    `;
  }}

//호출 부
<StyledButton color={color} {...rest}>
   {children}
</StyledButton>

Button.js에서도 비구조화 할당을 통해, 컴포넌트 태그에서 건네준 color와, App.js에서의 theme를 받아 사용할 수 있다.

createGlobalStyle``;

전역적으로 무언가를 적용하고 싶을때 사용 예를 들면 background

const GlobalStyle = createGlobalStyle`
  body{
    background: #e9ecef;
  }
`;
function App() {
  return (
    <~~~~>
      <GlobalStyle />
      <~~~>
        <~~~ />
        <~~~ />
        <~~~ />
      </~~~>
    </~~~>
  );
}

App.js에서 다음같이 파일을 만들어주고, 위 코드 처럼, 가장 밖에서 감싸고 있는 태그 안에 적어주기만 하면 배경색이 #e9ecef가 됨

profile
코딩의 고수가 되고 싶은 종한이

0개의 댓글