✍ 공부/React

React에서 styled-component 이용하기 + typescript

Po_tta_tt0 2022. 3. 28. 16:30
반응형

 

 

 

 

 

 

 

 

사용하는 이유

 

  • styled-components는 React css 스타일링 프레임워크로, CSS in JS이다
  • 따라서 JS에서 직접적으로 스타일에 영향을 줄 수 있다.
  • className을 따로 지정할 필요가 없다 => 빌드 시 고유한 클래스명이 적용된다.
  • CSS 문법을 따르기 때문에 가독성에 좋다
  • 새로운 component를 만들고 만들어둔 component를 다른 컴포넌트에 이용할 수 있어 효율적이다.
  • 중첩 스코프 규칙을 이용해 직관적인 코드 작성이 가능하다.
  • 일관적인 스타일 관리가 쉽다.
  • 반복적으로 쓰이는 요소를 정의해서 props로 가져다 쓸 수 있다.

 

 

 

 

시작하기

0. 설치

npm install --save styled-components // 기본
yarn add styled-components // yarn 사용 시

type 추가를 위해서는

npm i —save-dev @types/styled-components

도 설치해준다

 

 

 

 

1. 기본 셋팅하기

styled-component는 모든 페이지에 적용할 수 있는 스타일을 한번에 그릴 수 있다.

 

이를 위해서

 

<App.tsx>

import Router from "./Router";
import { ReactQueryDevtools } from "react-query/devtools";
import { GlobalStyle } from "./Globalstyles"; // 2 ✨
import { ThemeProvider } from "styled-components"; // 1 ✨
import { darkTheme, lightTheme } from "./theme"; // 1 ✨
import { useState } from 'react'

function App() {
const [isDark, setIsDark] = useState(false);
  return (
    <>
      <ThemeProvider theme={isDark ? darkTheme : lightTheme}> // 1 ✨
        <GlobalStyle /> // 2 ✨
        <Router />
        <ReactQueryDevtools initialIsOpen={true} />
      </ThemeProvider>
    </>
  );
}

export default App;

1. ThemeProvider로 전체를 감싸고

=> 바로 뒤에 선언할 'mainTheme'이 GlobalStyle을 포함한 전체에 영향을 미치게 하기 위해

2. GlobalStyle로 글로벌 스타일을 명시해줄 준비를 한다.

=> 모든 페이지에 통용되는 디자인 코드를 정의해주면서 의미없는 반복을 줄인다 ex) 폰트

 

 

 

1-1. ThemeProvider

 

*typescript를 사용할 경우

 

<theme.ts>

import { DefaultTheme } from "styled-components"; // ✨ 1

export const darkTheme: DefaultTheme = { // ✨ 1
  bgColor: "#353b48",
  textColor: "black",
  accentColor: "#487eb0",
};
export const lightTheme: DefaultTheme = { // ✨ 1
  bgColor: "#f5f6fa",
  textColor: "#353b48",
  accentColor: "#487eb0",
};

이렇게 반복적으로 사용되는 정보를 변수를 이용해 선언해주면 된다.

 

 

 

 

<Styled.d.ts>

import "styled-components"; // ✨ 1

declare module "styled-components" { // ✨ 1
  export interface DefaultTheme {
    textColor: string;
    bgColor: string;
    accentColor: string;
  }
}
  • styled-components를 import하고
  • styled components의 테마 정의를 확장하는게 목표

 

 

Typescript를 사용하지 않으면 Styled.d.ts는 만들지 않아도 된다.

 

 

 

1.2 GlobalStyle

 

<Globalstyles.ts>

import { createGlobalStyle } from "styled-components";  // ✨ 1

export const GlobalStyle = createGlobalStyle`  // ✨ 2
    
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, menu, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
main, menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, main, menu, nav, section {
  display: block;
}
/* HTML5 hidden-attribute fix for newer browsers */
*[hidden] {
    display: none;
}
body {
  line-height: 1;
}
menu, ol, ul {
  list-style: none;
}
blockquote, q {
  quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
  content: '';
  content: none;
}
table {
  border-collapse: collapse;
  border-spacing: 0;
}
*{
  box-sizing: border-box;
}
a{
  text-decoration: none
}
`;
  • styled-components에서 createGlobalStyle을 가져와서
  • export시키고 원하는 글로벌 css값들을 백틱 뒤에 적어준다.

 

 

 

 

2. 사용하기

 

2.1 기본

<StyledComponents.tsx>

import React, { useState } from "react";
import styled from 'styled-components' // ✨ 1

const StyledComponents = () => {
  const [isClick, setIsClick] = useState(false);

  const onClick = () => {
    setIsClick((prev) => !prev);
  };
  return (
    <>
      <div>
        <h1>스타일 컴포넌트를 어떻게 이용할까?</h1>
      </div>
      <div>
        <h2>리스트를 작성해보자</h2>
        <ul>
          <li>1</li>
          <li>2</li>
          <li>3</li>
          <li>4</li>
          <li>5</li>
        </ul>
        <button onClick={onClick}>클릭!</button>
      </div>
    </>
  );
};

export default StyledComponents;

styled-components를 사용하고 싶은 컴포넌트에 가서 import를 해준다.

return 밑으로 원래 방식대로 코딩을 해준다

 

 

 

import React, { useState } from "react";
import styled from "styled-components"; 

const Container = styled.div` // ✨ 2
  background-color: black;
`;

const StyledComponents = () => {
  const [isClick, setIsClick] = useState(false);

  const onClick = () => {
    setIsClick((prev) => !prev);
  };
  return (
    <Container> // ✨ 1 
      <div>
        <h1>스타일 컴포넌트를 어떻게 이용할까?</h1>
      </div>
      <div>
        <h2>리스트를 작성해보자</h2>
        <ul>
          <li>1</li>
          <li>2</li>
          <li>3</li>
          <li>4</li>
          <li>5</li>
        </ul>
        <button onClick={onClick}>클릭!</button>
      </div>
    </Container> // ✨ 1
  );
};

export default StyledComponents;

1. 그 후 이렇게 JSX 태그 이름을 원하는 이름으로 바꿔준다.

<></> 보다 Container이 직관적으로 태그 활용의 의도를 확인할 수 있기 때문에 편리하다.

 

그 후

const (바뀐 이름) = styled.(원래 태그)``(백틱)

을 사용해 백틱 안에 css를 작성해주면 된다

 

 

 

 

그 외에도

const MakeRootBtn = styled.button`
  border: none;
  outline: none;
  background-color: transparent;
  position: absolute;
  top: 3px;
  right: 3px;
  display: none;
  cursor: pointer;
  ${MainChat}:hover & {          /* ✨ 1 */
    display: flex;
  }
`;
  • ${MainChat} => 이라는 styled components 태그를
  • :hover => hover하게 되면
  • & {} : MakeRootBtn 자신의 display를 flex로 만든다

처럼 :hover , :nth-child등을 기본 css처럼 이용할 수 있으며

&를 이용해서 자기 자신을 다시 이용할 수도 있다.

 

더 자세한 내용은 공식문서를 참고하자

 

 

 

 

 

 

 

 

2.2 활용 (CSS in JS) + Typescript

 

<CandidateImg bgPhoto={`../image/${selector}.jpg`}>

return 안에 이렇게 props를 넣어주고

✨ bgPhoto ={}

 

const CandidateImg = styled.div<{ bgPhoto: string }>` /* ✨ 1 */
  border: 1px solid black;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding-bottom: 3rem;
  background-image: url(${(props) => props.bgPhoto}); /* ✨ 2 */
  background-size: cover;
  background-position: center;
`;

1. Typescript를 이용할 경우 type을 명시해준다 <{ bgPhoto: string }>

2. props로 받아온 bgPhoto 값을 이용하면 된다.

 

 

 

 

 

🙇‍♀️

https://styled-components.com/

반응형