Hyebin‘s blog
Published 2022. 3. 14. 11:19
styled-components Front-end/React

styled-components

설치

npm i styled-components

 

import

import styled from "styled-components";

 

고정 스타일링

import React from "react";
import styled from "styled-components";

const StyledButton = styled.button`
  padding: 0.375rem 0.75rem;
  border-radius: 0.25rem;
  font-size: 1rem;
  line-height: 1.5;
  border: 1px solid lightgray;
  color: gray;
  background: white;
`;

function Button({ children }) {
  return <StyledButton>{children}</StyledButton>;
}

가변 스타일링

Styled Components는 React 컴포넌트에 넘어온 props에 따라 다른 스타일을 적용하는 기능을 제공

버튼의 글자색과 배경색을 props따라 바뀌도록 위에서 작성한 예제 코드를 변경해보겠습니다. 자바스크립트의 ||연산자를 사용하여 props이 넘어오지 않은 경우, 기존에 정의한 기본 색상이 그대로 유지되도록 합니다.

import React from "react";
import styled from "styled-components";

const StyledButton = styled.button`
  padding: 0.375rem 0.75rem;
  border-radius: 0.25rem;
  font-size: 1rem;
  line-height: 1.5;
  border: 1px solid lightgray;

  color: ${(props) => props.color || "gray"};
  background: ${(props) => props.background || "white"};
`;

function Button({ children, color, background }) {
  return (
    <StyledButton color={color} background={background} Î>
      {children}
    </StyledButton>
  );
}
import Button from "./Button";
<Button color="green" background="pink">
  Green Button
</Button>;

가변 스타일링 2

prop에 따라 바꾸고 싶은 CSS 속성이 위와 같이 하나가 아니라 여러 개일 경우가 있습니다. 이럴 경우, Styled Components에서 제공하는 css 함수를 사용해서 여러 개의 CSS 속성을 묶어서 정의할 수 있습니다.

 

import

import styled, { css } from "styled-components";

 

예를 들어, primary prop이 넘어온 경우, 글자색을 흰색, 배경색과 경계색은 남색으로 변경하고 싶다면 다음과 같이 예제 코드를 수정할 수 있습니다. 이번에는 자바스크립트의 && 연산자를 사용해서, primary prop이 존재하는 경우에만 css로 정의된 스타일이 적용되도록 하였습니다.

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

const StyledButton = styled.button`
  padding: 0.375rem 0.75rem;
  border-radius: 0.25rem;
  font-size: 1rem;
  line-height: 1.5;
  border: 1px solid lightgray;

  ${(props) =>
    props.primary &&
    css`
      color: white;
      background: navy;
      border-color: navy;
    `}
`;

function Button({ children, name }) {
  return <StyledButton {name}>{children}</StyledButton>;
}

참고로 넘겨야할 prop 값이 많아질 경우, 위와 같이 ...props 구문을 사용해서 children 외에 모든 prop을 간편하게 전달할 수 있습니다.

자, 이제 다음과 같이 하나의 prop 만으로 여러가지 CSS 속성이 한 번에 적용된 버튼을 얻을 수 있습니다.

import Button from "./Button";
<Button primary>Primary Button</Button>;

ThemeProvider

참고 블로그 : https://wonit.tistory.com/366 ThemeProvider 가 바로 context를 사용해서 모든 리액트 컴포넌트에게 theme 속성을 전달하는 역할을 수행한다.

import React from "react";
import { ThemeProvider } from "styled-components";

const theme = {
  // ... 사용자 정의 theme code
}

const Home = () => {
  return (
    <ThemeProvider theme={theme}>
      <Header />
      <Sidebar />
      <HeroSection />
      <Footer />
    </ThemeProvider>
  );
}

Home 컴포넌트에서 최상단의 태그가 <ThemeProvider> 이므로 하위 자식의 모든 컴포넌트는 <ThemeProvider> 의 props로 넘어가는 theme 값을 사용할 수 있게되는 것

 

theme/theme.js

const theme = {
  mainColor: "#3498db",
  dangerColor: "#e74c3c",
  successColor: "#2ecc71",
};

export default theme;

App.js

import styled, { ThemeProvider } from "styled-components";
import React, { useState, useReducer } from "react";
import theme from "./theme/theme.js";

 const Card = styled.div`
    border-radius: 30px;
    padding: 25px 15px;
    background-color: ${(props) => props.theme.successColor};
  `;

function App(props) {
  return (
    <ThemeProvider theme={theme}>
        <Card />
    </ThemeProvider>
  );
}

export default App;

 

실제 응용 코드 예시

예를 들어 display:flex나 h1의 font-size, color를 ThemeProvider를 사용해서 공통 작업을 한다고 해보자.

import styled from "styled-components";

// 반응형 디자인을 위한 픽셀 컨버팅 함수const pixelToRem = (size) => `${size / 16}rem`;

// font size를 객체로 반환해주자.const fontSizes = {
  title: pixelToRem(60),
  subtitle: pixelToRem(30),
  paragraph: pixelToRem(18),
};

// 자주 사용하는 색을 객체로 만들자.const colors = {
  black: "#000000",
  grey: "#999999",
  green: "#3cb46e",
  blue: "#000080",
};

// 자주 사용하는 스타일 속성을 theme으로 만들어보자.const common = {
  flexCenter: `
    display: flex;
    justify-contents: center;
    align-items: center;
  `,
  flexCenterColumn: `
    display: flex;
    flex-direction: column;
    justify-contents: center;
    align-items: center;
  `,
};

// theme 객체에 감싸서 반환한다.const theme = {
  fontSizes,
  colors,
  common,
};

export default theme;

위에 파일에 나온 내용은 다음과 같다.

  1. font-size 통일
  2. color 통일
  3. display flex center 자동 생성기

그리고 App.js 파일에서 우리가 만든 theme들을 사용해보자.

import React from "react";
import styled, { ThemeProvider } from "styled-components";
import theme from "./theme";

const Container = styled.div`
  width: 100vw;
  height: 100vh;
  ${({ theme }) => theme.common.flexCenterColumn};
`;

const Title = styled.h1`
  font-size: ${({ theme }) => theme.fontSizes.title};
  color: ${({ theme }) => theme.colors.grey};
`;

const Subtitle = styled.h2`
  font-size: ${({ theme }) => theme.fontSizes.subtitle};
  color: ${({ theme }) => theme.colors.green};
`;

const Paragraph = styled.p`
  font-size: ${({ theme }) => theme.fontSizes.Paragraph};
  color: ${({ theme }) => theme.colors.blue};
`;

const App = () => {
  return (
    <div><ThemeProvider theme={theme}><Container><Title>Hello</Title><Subtitle>Welcome to styled-component's world</Subtitle><Paragraph>ThemeProvider에 대해서 배워볼까요?</Paragraph></Container></ThemeProvider></div>
  );
};

export default ThemeProviderPrac;

styled-components에서 props로 넘오는 객체 혹은 값들을 사용하려면 ${} 리터럴로 언패킹 해주면 된다!

 

 

createGlobalStyle

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

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

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

'Front-end > React' 카테고리의 다른 글

useRef  (0) 2022.03.14
Custom hook  (0) 2022.03.14
[React] useCallback  (0) 2022.03.09
[React] useMemo 원시타입/객체 타입  (0) 2022.03.09
Redux 란 ? Redux Setting Up - 1  (0) 2022.03.07
profile

Hyebin‘s blog

@hyebin Lee

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그