개발

[CSS라이브러리] styled-components

썽연 2022. 5. 21. 00:19
728x90

스타일 컴포넌트에 대해 배워보자~

리액트 파일을 먼저 만들어주느

yarn create react-app . (현재폴더에할거면 .)
폴더명은 소문자만 쓸 것

  • 대문자는 에러가 뜬다..

필요없는 파일 제거 및 코드 수정

index.js와 App.js를 제외한 모든 파일을 지워준다.

// src/index.js

import React from "react";
import App from "./App";
import { createRoot } from "react-dom/client";

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

root.render(<App />);
// src/App.js

function App() {
  return <>Hello!</>;
}

export default App;

styled-components 설치

yarn add styled-components

styled-components 사용해보기

컴포넌트에 styled-component import 해주기
import styled from “styled-components;

const 컴포넌트명 = styled.태그명`
	// 여기에 css작성해주기~~
`

스타일 컴포넌트를 사용할 때 꼭 백틱 으로 감싸서 css를 작성해준다.

styled-components 왜 사용하는데?
css를 살피지 않고 컴포넌트가 맡은 일을 알았으면 좋겠다!
인라인 방식을 사용하면 JS코드 방식을 사용하여 괄호도 사용하여 스타일을 해주어야하는데 이러지 않아도 된다!

 

<div style={{ display: "flex" }}>
    <div style={{ backgroundColor: "teal", width: 100, height: 100 }}></div>
    <div style={{ backgroundColor: "tomato", width: 100, height: 100 }}></div>
</div>

위 코드를 styled-components를 이용하여 아래와 같이 변경할 수 있다.

// 스타일 컴포넌트 적용

const Father = styled.div`
  display: flex;
`;
const BoxOne = styled.div`
  background-color: teal;
  width: 100px;
  height: 100px;
`;
const BoxTwo = styled.div`
  background-color: tomato;
  width: 100px;
  height: 100px;
`;
// App에서 렌더링 해주는 코드
<Father>
    <BoxOne />
    <BoxTwo />
</Father>

위에 styled-components를 사용한 코드를 보자.
BoxOne과 BoxTwo는 배경색을 제외하고 코드가 모두 똑같아 중복이 되고 있다!
⇒ 이러한 부분은 하나로 해결하자!
⇒ 어떻게? pros로 배경 색을 받자!

// styled-components에서 props를 받는방법
const Box = styled.div`
  background-color: ${(props) => props.bgColor};
  width: 100px;
  height: 100px;
`;

${props⇒ props.속성명} 을 이용하여 props값을 전달해준다.

// App.js에서 렌더링 해주는 코드
<Father>
    <Box bgColor="teal" />
    <Box bgColor="tomato" />
</Father>

속성명은 bgColor을 주었으므로 props값의 속성명을 그대로 전달해주자~~

스타일을 추가적으로 더 주고싶을 땐?

기존에 만든 스타일을 확장해보자!

const Circle = styled.div`
  background-color: ${(props) => props.bgColor};
  width: 100px;
  height: 100px;
	border-radius: 50px;
`;

위와 같이 Box의 스타일을 다 똑같이 가지고오고, Border-radius만 따로 추가해주는 코드를 작성하고 싶을 때가 있을 수 있다.
이럴땐 만든 스타일을 div태그 대신 사용하자!

const Circle = styled(Box)`
  border-radius: 50px;
`;

위 처럼 스타일을 만들어주면,

<Father>
    <Box bgColor="teal" />
    <Circle bgColor="tomato" />
</Father>

위와 같이 Circle도 너비와 높이가 100이면서, props를 이용하여 배경색상을 받을 수 있는 박스가 아닌 원형을 만들 수 있다!

스타일 확장이 아닌, HTML태그를 변경하고 싶다!

컴포넌트에서 렌더링해주는 곳의 코드에서

const Btn = styled.button`
  color: white;
  background-color: tomato;
  border: 0;
  border-radius: 15px;
`;

현재 Btn 스타일은 button 태그이다.

<Father>
    <Btn>Login</Btn>
    <Btn as="a" href="/">
      Login
    </Btn>
</Father>

하지만 위와 같이 as="태그명" 으로 변경하면, button 태그가 아닌 a태그로 사용할 수 있다.

스타일 컴포넌트에서 속성 주는법

const Input = styled.input.attrs({ required: true, minLength: 10 })`
  background-color: tomato;
`;

.attrs({}) 를 이용하여 속성을 객체형태로 줄 수 있다.
이렇게하면 Input이 여러개 일 때, required를 스타일컴포넌트에서 한 번만 지정해줄 수 있다.

<Father as="header">
	  <Input required />
	  <Input required />
	  <Input required />
	  <Input required />
	  <Input required />
	  <Input required />
</Father>

위와 같이 Input이 여러개 일 때 모두 필수 요소이면 required를 써주어야한다.
하지만! 스타일 컴포넌트에서 속성값으로 지정을 해주었기 때문에

<Father as="header">
    <Input />
    <Input />
    <Input />
    <Input />
    <Input />
    <Input />
</Father>

위처럼 사용하여도 모든 Input은 required가 되어있는 상태이다.

스타일 컴포넌트에 애니메이션 주기

keyframes를 import 해준다.
*import* styled, { keyframes } *from* "styled-components";

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

keyframs를 이용하여 애니메이션 효과를 css준다.

const Box = styled.div`
  width: 100px;
  height: 100px;
  background-color: tomato;
  animation: ${rotation} 1s linear infinite;
`;

animation 속성을 ${}를 이용하여 만들어준 효과를 적용해준다.

Themes

styled-components안에 ThemeProvider라는 것이 있는데, theme는 모든 색상 object가 다 있다.
obejct를 바꾸면 되는 것이며, 컴포넌트를 일일이 바꾸는 것이 아니다.
즉, 다크모드 구현할 때 글자색과 배경색을 Theme을 이용하여 바꾼다!

1. 먼저 index.js에서 import해준다.
*import* { ThemeProvider } *from* "styled-components";
2. 객체형식으로 Theme을 지정해준다.

const darkTheme = {
  textColor: "whitesmoke",
  backgroundColor: "#111",
};

const lightTheme = {
  textColor: "#111",
  backgroundColor: "whitesmoke",
};

3. App을 ThemeProvider로 묶어준다

root.render(
  <ThemeProvider theme={lightTheme}>
    <App />
  </ThemeProvider>
);

이 때 ThemeProvider의 theme을 위에서 만들어준 Theme으로 설정해준다.

728x90