React Component Styled-components

Big Jay·2022년 10월 19일
0

React 라이브러리

목록 보기
1/2

styled-components란?

React 컴포넌트 시스템을 스타일링하는 CSS-in-JS 라이브러리이다.

CSS-in-JS란?

기존 웹페이지의 경우 CSS, HTML, JS를 각각 분리하여 관리하였으나, React, vue, Angler 등에는 component 기반으로 개발이 진행된다. 이 때 해당 라이브러리를 사용하여 CSS, HTML, JS를 하나의 컴포넌트에 전부 관리가 가능하다.

특징

  • 스타일에 대한 고유한 클래스명을 생성하며, 중복, 철자 오류에 대해 걱정할 필요가 없다.
  • 페이지에서 렌더링되는 구성 요소를 추적하고 자동으로 해당 스타일만 삽입한다.
  • 수십 개의 클래스를 수동으로 관리할 필요 없이 props 또는 전역 theme 기반으로 구성 요소의 스타일을 적용하는것이 간단하고 직관적이다.

설치

npm i styled-components 
또는
yarn add styled-components

기본 문법

const 컴포넌트 명 = styled.태그명``

컴포넌트 명으로 변수를 지정하는데 이 때 시작은 대문자로 해야하며 태그명 뒤에는 ``(백틱) 기호를 사용하여 스타일을 적는다.

// 패키지에서 styled를 import
import styled from "styled-components"

// 변수명 = styled.태그명``
const Button = styled.button`
	width:100px;
	height:30px;
`

function App (){
	return (
    	<div>
      {/*위에서 정한 변수명을 태그처럼 사용하면 된다.*/}
      		<Button>버튼</Button>
      	</div>
    )
}
export default App;

❗️주의 사항으로 styled component는 함수 컴포넌트 밖에 위치해야 한다.

props를 사용한 스타일링

React는 컴포넌트에 props를 전달할 수 있는데 styled component도 props에 따라 다른 스타일을 적용할 수 있다.

// 패키지에서 styled를 import
import styled from "styled-components";

// 변수명 = styled.태그명``
const Button = styled.button`
  width: 100px;
  height: 30px;
  background-color: ${(props) => props.bgColor};
`;

function App() {
  return <div>
    {/* props로 배경색 정보 전달 시 이에 따른 스타일링이 가능하다 */}
    <Button bgColor="tomato">버튼</Button>
  </div>
}
export default App;

이와 같은 기능으로 다크모드와 같은 테마 변경도 가능하다.

스타일 확장하기

자주 사용하는 스타일 컴포넌트가 있고 거기서 추가로 확장하여 사용할 수 있다.

import styled from "styled-components";

// 변수명 = styled.태그명``
const Button = styled.button`
  width: 100px;
  height: 30px;
  border:0;
  background-color: ${(props) => props.bgColor};
`;

// 스타일을 가져올 컴포넌트명을 인자로 받는다.
const ExtendButton = styled(Button)`
  color: #fff;
  border-radius: 20px;
  margin-left: 10px;
`;

function App() {
  return <div>
    {/* props로 배경색 정보 전달 시 이에 따른 스타일링이 가능하다 */}
    <Button bgColor="tomato">버튼</Button>
    <ExtendButton bgColor="hotpink">확장</ExtendButton>
  </div>
}
export default App;

Element 교체

기존에 생성된 styled component의 스타일은 그대로 사용하며 Element만 교체를 하여 사용할 수 있다.

import styled from "styled-components";

// 변수명 = styled.태그명``
const Button = styled.button`
  width: 100px;
  height: 30px;
  border:0;
  background-color: ${(props) => props.bgColor};
`;

// 스타일을 가져올 컴포넌트명을 인자로 받는다.
const ExtendButton = styled(Button)`
  color: #fff;
  border-radius: 20px;
  margin-left: 10px;
`;

function App() {
  return <div>
    {/* as를 사용하여 element를 교체할 수 있다.*/}
    <Button as="div" bgColor="tomato">버튼</Button>
    <ExtendButton bgColor="hotpink">확장</ExtendButton>
  </div>
}
export default App;

Attaching 추가

import styled from "styled-components";

const Form = styled.form`
  display: flex;
  flex-direction: column;
  width: 300px;
`;

// attrs를 사용하여 추가 할 수 있다.
const InputText = styled.input.attrs({
  type: "text",
  required: true,
  minLength: "10"
})`
  padding: 5px;
  border-radius: 10px;
  border: 0;
  background-color: #dfdfdf;
  margin-bottom: 10px;
`;

const Button = styled.button`
  width: 100%;
  height: 30px;
  border: 0;
  background-color: ${(props) => props.bgColor};
`;

function App() {
  return (
    <Form>
      <InputText placeholder="이메일 입력" />
      <InputText placeholder="이름 입력" />
      <InputText placeholder="나이 입력" />
      <InputText placeholder="사는 지역" />
      <Button bgColor="tomato">버튼</Button>
    </Form>
  );
}
export default App;

Animation

styled components에는 keyframes helper를 사용하여 Animation 인스턴스를 생성할 수 있으며, 이를 component 스타일에 사용할 수 있다.

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

// keyframe helper를 사용하여 애니메이션을 만든다.
const rotate = keyframes`
0% {
    transform: rotate(0deg);
    border-radius: 0;
  }
50%{
  border-radius: 100px;
}
100% {
    transform: rotate(360deg);
    border-radius: 0px;
  }
`;

// 만든 animation은 다른 styled component에 사용할 수 있다.
const Box = styled.div`
  width: 100px;
  height: 100px;
  background-color: tomato;
  animation: ${rotate} 2s linear infinite;
`;

function App() {
  return <Box />;
}
export default App;

styled component selector

style을 작성할 때 seletor로 태그, 클래스명, Id 등 여러가지로 지정할 수 있지만 styled components에서는 다른 스타일 컴포넌트를 selector로 지정할 수가 있다.

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

const rotate = keyframes`
0% {
    transform: rotate(0deg);
    border-radius: 0;
  }
50%{
  border-radius: 100px;
}
100% {
    transform: rotate(360deg);
    border-radius: 0px;
  }
`;

const Emoji = styled.span`
  font-size: 36px;
`;

const Box = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100px;
  height: 100px;
  background-color: tomato;
  animation: ${rotate} 2s linear infinite;
  ${Emoji}:hover {
    font-size: 90px;
  }
`;

function App() {
  return (
    <Box>
      <Emoji>🇰🇷</Emoji>
    </Box>
  );
}
export default App;

Theming

ThemeProvider라는 Context API 사용하여 앱 전체의 테마 지원한다.

//index.js
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import {ThemeProvider} from "styled-components"

import App from "./App";

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

const darkMode = {
  textColor:"whitesmoke",
  bgColor: "#000"
}

const lightMode = {
  textColor:"#333",
  bgColor: "whitesmoke"
}

root.render(
  <StrictMode>
    {/* ThemeProvider로 감싼 후 Props로 테마 정보를 전달하면 된다. */}
    <ThemeProvider theme={darkMode}>
    <App />
    </ThemeProvider>
  </StrictMode>
);

위에서 전달 받은 Theme의 속성 정보를 Styled components에서 props로 사용 할 수 있다.

import styled from "styled-components";

const Emoji = styled.span`
  font-size: 36px;
`;

const Box = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100px;
  height: 100px;
  /* props로 theme 속성을 가져올 수 있다. */
  background-color: ${props => props.theme.bgColor};
  ${Emoji}:hover {
    font-size: 90px;
  }
`;

function App() {
  return (
    <>
      <Box>
        <Emoji>🇰🇷</Emoji>
      </Box>
      <Emoji>🇰🇷</Emoji>
    </>
  );
}
export default App;

참고

profile
안녕하세요.

0개의 댓글