React ์ปดํฌ๋„ŒํŠธ css ์Šคํƒ€์ผ๋ง ๊ธฐ๋ณธ / Style Components(prop๋กœ ํ™•์žฅ, as, ์†์„ฑ ์ถ”๊ฐ€, ์• ๋‹ˆ๋ฉ”์ด์…˜, ๊ฐ€์ƒ ์„ ํƒ์ž)

2023. 8. 13. 20:20ใ†Study_Develop/React

๋ฐ˜์‘ํ˜•

 

React ์ปดํฌ๋„ŒํŠธ css ์Šคํƒ€์ผ๋ง ๊ธฐ๋ณธ

 

๊ธฐ๋ณธ์ด๋ผ๊ธฐ ๋ณด๋‹ค๋Š”, react์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณ„๋„์˜ css-in-js๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์—†์ด ์ˆœ์ˆ˜ํ•˜๊ฒŒ css๋กœ๋งŒ ์Šคํƒ€์ผํ•˜๋Š” ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๊ฒ ๋‹ค.

 

Inline Style

 

๊ฐ€์žฅ ๊ฐ„๋‹จํ•˜๊ณ  ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ React ์ปดํฌ๋„ŒํŠธ์— css์ธ๋ผ์ธ ์Šคํƒ€์ผ์„ ๋ฐ”๋กœ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์ผ๋ฐ˜์ ์ธ ์›น ํŽ˜์ด์ง€์—์„œ ์ธ๋ผ์ธ ์Šคํƒ€์ผ์„ ์ ์šฉํ•  ๋–„์ฒ˜๋Ÿผ html์—˜๋ฆฌ๋จผํŠธ์˜ style์†์„ฑ์„ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

ํ•˜์ง€๋งŒ, React๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์ž‘์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์›นํŽ˜์ด์ง€์—์„œ ์ธ๋ผ์ธ ์Šคํƒ€์ผ์„ ์ ์šฉํ•  ๋•Œ์™€ ์•ฝ๊ฐ„์˜ ์ฐจ์ด์ ์ด ์žˆ๋‹ค.

 

-style ์†์„ฑ๊ฐ’์— ์ผ๋ฐ˜ ๋ฌธ์ž์—ด์ด ์•„๋‹Œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด๊ฐ€ ํ• ๋‹น๋˜์•ผ ํ•œ๋‹ค.

- CSS ์†์„ฑ๋ช…์ด ์ผ€๋ฐฅ ์ผ€์ด์Šค(kebab case)์ด ์•„๋‹Œ ์นด๋ฉœ ์ผ€์ด์Šค(camel case)๋กœ ์ž‘์„ฑ๋˜์•ผ ํ•œ๋‹ค.

 

์ด๋•Œ ์นด๋ฉœ ์ผ€์ด์Šค๋ž€ var camelCase; ์™€ ๊ฐ™์ด ์ค‘๊ฐ„ ๊ธ€์ž๋“ค์€ ๋Œ€๋ฌธ์ž๋กœ ์‹œ์ž‘ํ•˜์ง€๋งŒ ์ฒซ ๊ธ€์ž๊ฐ€ ์†Œ๋ฌธ์ž์ธ ๊ฒฝ์šฐ์—๋Š” ๋‚™ํƒ€์™€ ๋ชจ์–‘์ด ๋น„์Šทํ•˜๋‹คํ•˜์—ฌ ์นด๋ฉœ ์ผ€์ด์Šค๋ผ๊ณ  ํ•œ๋‹ค.

 

import React from "react";

const btnStyle = {
  color: "white",
  background: "teal",
  padding: ".375rem .75rem",
  border: "1px solid teal",
  borderRadius: ".25rem",
  fontSize: "1rem",
  lineHeight: 1.5,
};

function Button() {
  return <button style={btnStyle}>Inline</button>;
}

 

External Stylesheet

 

React์ปดํฌ๋„ŒํŠธ ํŒŒ์ผ์—์„œ ํ•ด๋‹น cssํŒŒ์ผ์„ ์ž„ํฌํŠธ ํ•˜๋Š” ๋ฐฉ๋ฒ•

๊ทธ ๋‹ค์Œ, ์—˜๋ฆฌ๋จผํŠธ์˜ className์†์„ฑ์„ ์ด์šฉํ•ด์„œ ์™ธ๋ถ€ ํŒŒ์ผ์— ์ •์˜๋œ ์Šคํƒ€์ผ์„ ๋งตํ•‘์‹œ์ผœ์ฃผ๋Š” ๊ฒƒ

 

์˜ˆ๋ฅผ ๋“ค์–ด, Button.cssํŒŒ์ผ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์Šคํƒ€์ผ์„ ์ •์˜ํ•œ๋‹ค.

 

.btn {
  color: white;
  background: teal;
  padding: 0.375rem 0.75rem;
  border: 1px solid teal;
  border-radius: 0.25rem;
  font-size: 1rem;
  line-height: 1.5;
}

 

๊ทธ๋ฆฌ๊ณ  ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž‘์„ฑ๋œ Button.jsํŒŒ์ผ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์œ„ cssํŒŒ์ผ์„ ์ž„ํฌํŠธํ•œ๋‹ค.

์ด๋•Œ ์†์„ฑ๋ช…์„ class ๋Œ€์‹ ์— className๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.

 

import React from "react";
import "./Button.css";

function Button() {
  return <button className="btn">External</button>;
}

 

์ด๋Ÿฐ ๋ฐฉ์‹

 

CSS Modules

 

์œ„์—์„œ ์†Œ๊ฐœํ•œ ์™ธ๋ถ€ ์Šคํƒ€์ผ ์‹œํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ React์•ฑ์˜ ๊ทœ๋ชจ๊ฐ€ ์ปค์ง์— ๋”ฐ๋ผ css ํด๋ž˜์Šค ์ด๋ฆ„์ด ๊ฒน์น˜๊ฒŒ ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์ปค์ง„๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ธ€๋กœ๋ฒŒ ๋„ค์ž„ ์ŠคํŽ˜์ด์Šค (global namespace)๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋งŒ์•ฝ 2๊ฐœ์˜ cssํŒŒ์ผ์— ๋™์ผํ•œ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ์ •์˜๊ฐ€ ๋˜์–ด ์žˆ๋‹ค๋ฉด, ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ ์ ์šฉ๋œ ์—˜๋ฆฌ๋จผํŠธ๋Š” 2๊ฐœ์˜ ์Šคํƒ€์ผ์— ๋ชจ๋‘ ์˜ํ–ฅ์„ ๋ฐ›๋Š”๋‹ค.

 

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ฐ css ํŒŒ์ผ์— ๊ณ ์œ ์˜ ๋„ค์ž„ ์ŠคํŽ˜์ด์Šค๋ฅผ ๋ถ€์—ฌํ•ด์ฃผ๋Š” css๋ชจ๋“ˆ(css modules)์ด๋ผ๋Š” ๊ธฐ๋ฒ•์ด ์žˆ๋‹ค. 

react์ปดํฌ๋„ŒํŠธ์— css๋ชจ๋“ˆ์„ ํ†ตํ•ด ์Šคํƒ€์ผ์„ ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

 

- ์™ธ๋ถ€ ์Šคํƒ€์ผ ์‹œํŠธ๋ฅผ ์ž‘์„ฑํ•  ๋–„, .cssํ™•์žฅ์ž๊ธฐ ์•„๋‹Œ, .module.cssํ™•์žฅ์ž๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

- react์ปดํฌ๋„ŒํŠธ ํŒŒ์ผ์—์„œ ์ž„ํฌํŠธ ํ•  ๋•Œ, ์ž„ํฌํŠธ๋œ css๋ชจ๋“ˆ์˜ ์ด๋ฆ„์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•ด์ค€๋‹ค. (import module_name from "./my/style.module.css";) ์ด๋Ÿฐ ๋ฐฉ์‹

 

- ์—˜๋ฆฌ๋จผํŠธ className ์†์„ฑ์„ ํ• ๋‹นํ•ด์ค„ ๋•Œ, ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ ์–ด๋Аcss ์†Œ์†์ธ์ง€ ์•Œ๋ ค์ค€๋‹ค.

 

import React from "react";
import styles from "./Button.module.css";

function Button() {
  return <button className={styles.btn}>Module</button>;
}

export default Button;

 

์š”๋Ÿฐ ๋ฐฉ์‹

 


 

Styled Components๋กœ React ์ปดํฌ๋„ŒํŠธ ์Šคํƒ€์ผ

 

CSS in JS?

 CSS in JS๋Š” ์Šคํƒ€์ผ ์ •์˜๋ฅผ CSSํŒŒ์ผ์ด ์•„๋‹Œ JS๋กœ ์ž‘์„ฑ๋œ ์ปดํฌ๋„ŒํŠธ์— ๋ฐ”๋กœ ์‚ฝ์ž…ํ•˜๋Š” ์Šคํƒ€์ผ ๊ธฐ๋ฒ•์ด๋‹ค.

 

์›นํŽ˜์ด์ง€๋ฅผ HTML, CSS, JS 3๊ฐœ๋กœ ๋ถ„๋ฆฌํ–ˆ๋˜ ๊ฒƒ์ด ๊ธฐ์กด์˜ ์›น์‚ฌ์ดํŠธ๋ฅผ ๊ฐœ๋ฐœํ•  ๋•Œ ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉํ–ˆ๋˜ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ React, Vue, Angular์™€ ๊ฐ™์€ ๋ชจ๋˜ js๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ธ๊ธฐ๋ฅผ ๋Œ๋ฉด์„œ ์›น ๊ฐœ๋ฐœ์˜ ํŒจ๋Ÿฌ๋‹ค์ž„์ด ๋ฐ”๋€Œ๊ณ  ์žˆ๋‹ค. ์ตœ๊ทผ์—๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์žฌํ™œ์šฉ์ด ๊ฐ€๋Šฅํ•œ ๋นŒ๋”ฉ ๋ธ”๋ก์œผ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ฐœ๋ฐœํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ ๊ฐœ๋ฐœ ๋ฐฉ๋ฒ•์ด ์ฃผ๋ฅ˜๊ฐ€ ๋˜๊ณ  ์žˆ๋‹ค.

 

๋”ฐ๋ผ์„œ, ๊ฐ ์ปดํฌ๋„ŒํŠธ์— html, css, js๋ฅผ ๋ชฝ๋•… ๋•Œ๋ ค๋ฐ•๋Š” ํŒจํ„ด์ด ๋งŽ์ด ์‚ฌ์šฉ๋œ๋‹ค. React๋Š” jsx๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ด๋ฏธ js๊ฐ€ html์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ํ˜•ํƒœ๋ฅผ ์ทจํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ์—ฌ๊ธฐ์— css-in-js๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋งŒ ์‚ฌ์šฉํ•˜๋ฉด css๋„ ์† ์‰ฝ๊ฒŒ js์— ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

ํŒจํ‚ค์ง€ ์„ค์น˜

Styled Components๋Š” styled-components๋ผ๋Š” npmํŒจํ‚ค์ง€ ๋ช…์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

 

npm i styled-components

 

๊ธฐ๋ณธ ๋ฌธ๋ฒ•

 

- html ํƒœ๊ทธ์— ๋Œ€ํ•ด์„œ ์ด๋ฏธ ์†์„ฑ์ด ์ •์˜๋˜์–ด ์žˆ๊ธฐ ๋–„๋ฌธ์— ํ•ด๋‹น ํƒœ๊ทธ๋ช…์˜ ์†์„ฑ์— ์ ‘๊ทผํ•œ๋‹ค.

 

import styled from "styled-components";

styled.button`
  // <button> HTML ์—˜๋ฆฌ๋จผํŠธ์— ๋Œ€ํ•œ ์Šคํƒ€์ผ ์ •์˜
`;

 

- React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์Šคํƒ€์ผ๋ง ํ•  ๋•Œ๋Š” ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž„ํฌํŠธ ํ›„ ํ•ด๋‹น ์ธ์ž๋กœ ๋„˜๊ธฐ๋ฉด ๋œ๋‹ค.

 

import styled from "styled-components";
import Button from "./Button";

styled(Button)`
  // <Button> React ์ปดํฌ๋„ŒํŠธ์— ์Šคํƒ€์ผ ์ •์˜
`;

 

๊ณ ์ • ์Šคํƒ€์ผ๋ง

 

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

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

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

 

์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉ์ด ๋œ๋‹ค.

 

import Button from "./Button";
<Button>Default Button</Button>;

 

์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ์Šคํƒ€์ผ์ด ์ ์šฉ๋œ ์ด ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค๋ฅธ React์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด

 

<button class="sc-kgAjT beQCgz">Default Button</button>

 

๋ธŒ๋ผ์šฐ์ €์—์„œ ๊ฐœ๋ฐœ์ž๋„๊ตฌ๋ฅผ ๋ˆ„๋ฅธ ํ›„, ์†Œ์Šค๋ฅผ ๋ด๋ณด๋ฉด <button>html์—˜๋ฆฌ๋จผํŠธ์— Styled Components๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ค€ ํด๋ž˜์Šค ์ด๋ฆ„์ด ์ ์šฉ๋˜์–ด ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

 

๊ฐ€๋ณ€ ์Šคํƒ€์ผ๋ง( porps ํ•œ ๊ฐœ ์ „๋‹ฌ )

 

Styled Compnents๋Š” React ์ปดํฌ๋„ŒํŠธ์— ๋„˜์–ด์˜จ porps์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์Šคํƒ€์ผ์„ ์ ์šฉํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.

Tagged Template Literals์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜๋„ ๋ฌธ์ž์—ด ์•ˆ์— ํฌํ•จ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

 

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

function Example() {
  const [email, setEmail] = useState("");

  return (
    <ExampleWrap active={email.length}>
      <Button>Hello</Button>
      <NewButton color="blue">Im new Button</NewButton>
    </ExampleWrap>
  );
}

const ExampleWrap = styled.div`
  background: ${({ active }) => {
    if (active) {
      return "white";
    }
    return "#eee";
  }};
  color: black;
`;

const Button = styled.button`
  width: 200px;
  padding: 30px;
`;

// Button ์ปดํฌ๋„ŒํŠธ ์ƒ์†
const NewButton = styled.Button`
  // NewButton ์ปดํฌ๋„ŒํŠธ์— color๊ฐ€๋Š” props๊ฐ€ ์žˆ์œผ๋ฉด ๊ทธ ๊ฐ’ ์‚ฌ์šฉ, ์—†์œผ๋ฉด 'red' ์‚ฌ์šฉ
  color: ${props => props.color || "red"};
`;

export default Example;

 

- styled-component๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์žฅ์  ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ณ€์ˆ˜์— ์˜ํ•ด ์Šคํƒ€์ผ์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.

 

- ์œ„ ์˜ˆ์‹œ๋ฅผ ๋ณด๋ฉด, email์ด๋ผ๋Š” state๊ฐ’์— ๋”ฐ๋ผ ExampleWrap์— prop์œผ๋กœ ๋‚ด๋ ค์ค€ active๋ผ๋Š” ๊ฐ’์ด true or false๋กœ ๋ฐ”๋€Œ๊ฒŒ ๋œ๋‹ค.

 

- styled-component๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ props์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ณ , ๊ทธ props์— ๋”ฐ๋ผ ์Šคํƒ€์ผ์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

 

- ํ•ด๋‹น ํŒŒ์ผ์—์„œ ์ •์˜ํ•œ css ๋ฅผ exportํ•˜์—ฌ ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ importํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

๊ฐ€๋ณ€ ์Šคํƒ€์ผ๋ง ( props ์—ฌ๋Ÿฌ ๊ฐœ ์ „๋‹ฌ )

 

- prop ์— ๋”ฐ๋ผ ๋ฐ”๊พธ๊ณ  ์‹ถ์€ css์†์„ฑ์ด ์œ„์™€ ๊ฐ™์ด ํ•˜๋‚˜๊ฐ€ ์•„๋‹ˆ๋ผ ์—ฌ๋Ÿฌ ๊ฐœ์ผ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

 

- ์ด๋Ÿด ๊ฒฝ์šฐ, Styled Components ์—์„œ ์ œ๊ณตํ•˜๋Š” cssํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ css์†์„ฑ์„ ๋ฌถ์–ด์„œ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

- ์˜ˆ๋ฅผ ๋“ค์–ด, primary porp์ด ๋„˜์–ด์˜จ ๊ฒฝ์šฐ, ๊ธ€์ž์ƒ‰์„ ํฐ์ƒ‰, ๋ฐฐ๊ฒฝ์ƒ‰๊ณผ ๊ฒฝ๊ณ„์ƒ‰์€ ๋‚จ์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์˜ˆ์ œ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. && ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด์„œ primary prop์ด ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ css๋กœ ์ •์˜๋œ ์Šคํƒ€์ผ์ด ์ ์šฉ๋˜๋„๋ก ํ•˜์˜€๋‹ค.

 

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

const StyledButton = styled.button`
  padding: 6px 12px;
  border-radius: 8px;
  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, ...props }) {
  return <StyledButton {...props}>{children}</StyledButton>;
}

 

- ${(props) => ...} ๋ถ€๋ถ„์€ props.primary๊ฐ€ true์ธ ๊ฒฝ์šฐ์— css ์ฝ”๋“œ๋ฅผ ์ ์šฉ์‹œํ‚จ๋‹ค.

 

- Button ์ปดํฌ๋„ŒํŠธ๋Š” StyledButton ์„ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, ๋ฒ„ํŠผ ๋‚ด์šฉ children๊ณผ ๋‹ค๋ฅธ ์†์„ฑ props์„ styledButton์— ์ „๋‹ฌํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Button์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒ„ํŠผ์„ ์ƒ์„ฑํ•˜๊ณ  ์›ํ•˜๋Š” ์†์„ฑ์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

- ์ฐธ๊ณ ๋กœ ๋„˜๊ฒจ์•ผํ•  prop ๊ฐ’์ด ๋งŽ์•„์งˆ ๊ฒฝ์šฐ, ์œ„์™€ ๊ฐ™์ด ...props๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ด์„œ children์™ธ์— ๋ชจ๋“  prop์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์˜ˆ์ œ ๋” ๋ณด๊ธฐ & ์†์„ฑ ๋” ๋ณด๊ธฐ

 

... ์ƒ๋žต

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

const App = () => {
  return (
    <Wrapper>
      <Box bgColor={"#cf6a87"} />
      <Box bgColor={"#574b90"} />
    </Wrapper>
  );
};

 

- BoxOne, BoxTwo ๋‘๊ฐ€์ง€ ์ปดํฌ๋„ŒํŠธ๋ฅผ box๋ผ๋Š” ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ๋กœ ํ†ตํ•ฉํ•˜๊ณ  bgColor๋ผ๋Š” ์†์„ฑ์„ ํ†ตํ•ด ๊ฐ๊ฐ ๋ฐฐ๊ฒฝ์ƒ‰์„ ์ง€์ •ํ•ด์ฃผ์—ˆ๋‹ค. ์ฒ˜์Œ์˜ ์ฝ”๋“œ๋ณด๋‹ค ์žฌ ์‚ฌ์šฉ์„ฑ์ด ํฌ๊ฒŒ ์ฆ๊ฐ€ํ–ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

์œ„์˜ Box ์ปดํฌ๋„ŒํŠธ์™€ ๊ฐ™์€ ํฌ๊ธฐ๋ฅผ ๊ฐ€์ง„ Circle ์ปดํฌ๋„ŒํŠธ ๋งŒ๋“ค์–ด๋ณด๊ธฐ

 

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

 

- border-radius ์†์„ฑ์„ ์ œ์™ธํ•˜๊ณ ๋Š” Box์ปดํฌ๋„ŒํŠธ์™€ ๋‹ค๋ฅผ๊ฒŒ ์—†๋‹ค. Styled Components์—์„œ๋Š” ์ด๋Ÿฐ ์ฝ”๋“œ์˜ ์ค‘๋ณต์„ ๋ง‰๊ธฐ ์œ„ํ•ด html์˜ ํƒœ๊ทธ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, Styled Components๋ฅผ ํ†ตํ•ด ๋งŒ๋“  ์ปดํฌ๋„ŒํŠธ๋„ ๋‹ค์‹œ ์ •์˜ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

- ์ฐจ์ด์ ์ด๋ผ๋ฉด styled(ComponentName)์™€ ๊ฐ™์ด ์ปดํฌ๋„ŒํŠธ ๋ช…์„ ๊ด„ํ˜ธ ์•ˆ์— ๋„ฃ์–ด์ค˜์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ ํ•˜๋‚˜๋ฟ์ด๋‹ค.

 

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

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

const App = () => {
  return (
    <Wrapper>
      <Box bgColor={"#cf6a87"} />
      <Box bgColor={"#574b90"} />
      <Circle bgColor={"black"} />
    </Wrapper>
  );
};

 

์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ!!

 

as ์†์„ฑ

 

๋งŒ์•ฝ, box๊ฐ€ ์˜ˆ๋ป์„œ ๋‹ค๋ฅธ ๊ณณ์—์„œ ๋ฒ„ํŠผ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์–ด์งˆ ์ˆ˜๋„ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ box๋Š” div๋กœ ์ •์˜๋˜์–ด ์žˆ๊ณ , ์›๋ž˜์˜ box์™€ ๋™์‹œ์— ์‚ฌ์šฉํ•˜๋ฉด์„œ ์ค‘๋ณต๋˜๋Š” ์ฝ”๋“œ๋„ ๋งŒ๋“ค๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๋ฉด?

 

๊ทธ๋Ÿด ๋•Œ์—๋Š” ์•„์ฃผ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ปดํฌ๋„ŒํŠธ ํƒœ๊ทธ์— as์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

 

const App = () => {
  return (
    <Wrapper>
      <Box bgColor={"#cf6a87"} />
      <Box as="button" bgColor={"#574b90"} />
      <Circle bgColor={"black"} />
    </Wrapper>
  );
};

 

์ด๋ ‡๊ฒŒ ํ•˜๊ณ  ๋ธŒ๋ผ์šฐ์ €์—์„œ ์š”์†Œ๋ฅผ ์ผœ๋ณด๋ฉด div๊ฐ€ button์œผ๋กœ ๋ฐ”๋€ ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์†์„ฑ ์ถ”๊ฐ€

 

required ์†์„ฑ์„ ๊ฐ€์ง„ inputํƒœ๊ทธ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ํ•„์š”ํ•œ ๊ฒฝ์šฐ, ๊ฐ๊ฐ์˜ ํƒœ๊ทธ๋งˆ๋‹ค required์†์„ฑ์„  ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ๋ฒˆ๊ฑฐ๋กญ๊ณ  ๊ท€์ฐฎ๋‹ค. ๋งŒ์•ฝ ์ˆ˜์ •ํ•  ์ผ์ด ์ƒ๊ธด๋‹ค๋ฉด, ํ•˜๋‚˜์”ฉ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์€ ๋”๋”์šฑ ๊ท€์ฐฎ๋‹ค.

 

styled Components์—์„œ๋Š” htmlํƒœ๊ทธ์˜ ์†์„ฑ๋„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

const Input = styled.input.attrs({ required:true })`
    background-color: orange;
    margin-right: 5px;
`;

 

 

์• ๋‹ˆ๋ฉ”์ด์…˜

 

Styled COmponents๋ฅผ ํ†ตํ•ด ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋„ฃ๊ธฐ ์œ„ํ•ด์„œ keyframes๋ฅผ import ํ•ด์•ผ ํ•œ๋‹ค.

 

import {keyframes} from "styled-components";

 

circle์— ์ƒ‰๊น”์ด ๋ฐ”๋€Œ๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ถ”๊ฐ€ํ•˜๋ฉด

 

import {keyframes} from "styled-components";

const CircleAnimation = keyframes`
  0% {
    background-color:red;
  }
  33% {
    background-color:green;
  }
  66%
  {
    background-color:blue;
  }
  100% {
    background-color:red;
  }
`;

const Circle = styled(Box)`
  border-radius: 50%;
  animation: ${CircleAnimation} 3s linear infinite;
`;

const App = () => {
  return (
    <Wrapper>
      <Circle bgColor={"red"} />
    </Wrapper>
  );
};

 

์—ฌ๊ธฐ์„œ ์ฃผ์˜! ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ปดํฌ๋„ŒํŠธ๋ณด๋‹ค ๋จผ์ € ์ •์˜ํ•ด์ฃผ์–ด์•ผ ์„ฑ๊ณต์ ์œผ๋กœ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์ ์šฉ๋œ๋‹ค.

์ˆœ์„œ๊ฐ€ ๋ฐ”๋€๋‹ค๋ฉด ์—๋Ÿฌ๋ฉ”์‹œ์ง€๊ฐ€ ๋œจ๋‹ˆ ์ฃผ์˜!

 

 

๊ฐ€์ƒ ์„ ํƒ์ž

 

์„ ํƒ์ž? 

 

๋ง ๊ทธ๋Œ€๋กœ ์„ ํƒ์„ ํ•ด์ฃผ๋Š” ์š”์†Œ

์ด๋ฅผ ํ†ตํ•ด ํŠน์ • ์š”์†Œ๋“ค์„ ์„ ํƒํ•˜์—ฌ ์Šคํƒ€์ผ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

 

 

๋จผ์ €, ์„ ํƒ์ž๋ฅผ ์•Œ์•„๋ณด๊ธฐ ์œ„ํ•ด Box์ปดํฌ๋„ŒํŠธ ๋‚ด์— spanํƒœ๊ทธ ํ•˜๋‚˜๋ฅผ ์ถ”๊ฐ€ํ•ด๋ณด์•˜๋‹ค.

 

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

  display: flex;
  justify-content: center;
  align-items: center;

  span {
    background-color: black;
  }
`;

const App = () => {
  return (
    <Wrapper>
      <Box bgColor={"#cf6a87"}>
        <span>๐Ÿ˜Š</span>
      </Box>
    </Wrapper>
  );
};

 

 

 

 

 

๊ฐ€์ƒ ์„ ํƒ์ž

 

span์œ„์— ๋งˆ์šฐ์Šค๋ฅผ ์˜ฌ๋ ธ์„ ๋•Œ (hover), ๋ฐฐ๊ฒฝ ์ƒ‰์ƒ์„ ๋ฐ”๊พธ๊ธฐ ์œ„ํ•œ ๋‘๊ฐ€์ง€ ๋ฐฉ๋ฒ•

 

// 1๋ฒˆ ๋ฐฉ๋ฒ•
const Box = styled.div`

์ƒ๋žต...

span {
  background-color: black;
}
span:hover {
  background-color: white;
}
`;

// 2๋ฒˆ ๋ฐฉ๋ฒ•
const Box = styled.div`
span {
  background-color: black;
  
  &:hover {
    background-color: white;
  }
}
`;