Emotion ์œผ๋กœ React ์ปดํฌ๋„ŒํŠธ ์Šคํƒ€์ผ๋ง

2023. 8. 14. 15:43ใ†Study_Develop/React

๋ฐ˜์‘ํ˜•

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

 

npm i @emotion/react

 

Emotion์€ ๋ฐ˜๋“œ์‹œ React ํ”„๋กœ์ ํŠธ์—์„œ๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

์ผ๋ฐ˜ jsํ”„๋กœ์ ํŠธ์—์„œ๋Š” @emotion/cssํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜๋ฉด ๋œ๋‹ค.

 

 

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

 

Styled Components์˜ ๊ฝƒ์ด styled()ํ•จ์ˆ˜์˜€๋‹ค๋ฉด, Emotion์˜ ๊ฝƒ์€ css()ํ•จ์ˆ˜์ด๋‹ค.

์˜ค๋žœ ๊ธฐ๊ฐ„ ๋™์•ˆ ๋‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์„œ๋กœ ๊ฒฝ์Ÿํ•˜๋ฉด์„œ ํ˜„์žฌ๋Š” Styled Components๋„ css()ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , 

Emotion๋„ ๋’ค์งˆ์„ธ๋ผ styled()ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋‹ค.

 

ํ•จ์ˆ˜๋Š” css ์„ ์–ธ ๋‚ด์šฉ์„ ์ธ์ž๋กœ ๋ฐ›๋Š”๋ฐ ๊ฐ์ฒดํ˜•์œผ๋กœ ๋„˜๊ฒจ๋„ ๋˜๊ณ , ๋ฌธ์žํ˜•์œผ๋กœ ๋„˜๊ฒจ๋„ ๋œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  css() ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ๊ฒฐ๊ณผ๋ฅผ ํ•ด๋‹น ์Šคํƒ€์ผ์„ ์ ์šฉํ•˜๊ณ  ์‹ถ์€ HTML ์š”์†Œ๋‚˜ React ์ปดํฌ๋„ŒํŠธ์˜ css๋ผ๋Š” prop์— ๋„˜๊ฒจ์ฃผ๋ฉด ๋œ๋‹ค.

 

 

- ๊ฐ์ฒดํ˜• ์Šคํƒ€์ผ

/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";

function MyComponent() {
  return (
    <div
      css={css({
        backgroundColor: "yellow",
      })}
    >
      ๋…ธ๋ž€์ƒ‰ ์˜์—ญ
    </div>
  );
}

 

- ๋ฌธ์žํ˜• ์Šคํƒ€์ผ

/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";

function MyComponent() {
  return (
    <div
      css={css`
        background-color: yellow;
      `}
    >
      ๋…ธ๋ž€์ƒ‰ ์˜์—ญ
    </div>
  );
}

 

Emotion ๋ฌธ์„œ์—์„œ๋Š” ๊ฐ€๊ธ‰์  ์Šคํƒ€์ผ์„ ๊ฐ์ฒด๋กœ ์„ ์–ธํ•ด์„œ css() ํ•จ์ˆ˜์— ๋„˜๊ธฐ๋ผ๊ณ  ๊ถŒ์žฅํ•˜๊ณ  ์žˆ๋Š”๋ฐ์š”. ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด css() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ์„ ์ƒ๋žตํ•˜๊ณ  css prop์— ๋ฐ”๋กœ ๊ฐ์ฒด๋ฅผ ๋„˜๊ธธ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํŠนํžˆ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ(TypeScript)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํƒ€์ž… ์ฒดํ‚น(type checking)์„ ํ†ตํ•ด ๋ฒ„๊ทธ๋„ ์ค„์ผ ์ˆ˜ ์žˆ๊ธฐ ๋–„๋ฌธ์ด๋‹ค.

 

 

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

 

<button> ์š”์†Œ์˜ css prop์„ ํ†ตํ•ด์„œ ๋‹ค์–‘ํ•œ css ์†์„ฑ ์ •์˜๋ฅผ ๊ฐ์ฒด๋กœ ๋„˜๊ฒจ๋ณด๊ธฐ

 

/** @jsxImportSource @emotion/react */

function Button({ children }) {
  return (
    <button
      css={{
        borderRadius: "6px",
        border: "1px solid rgba(27, 31, 36, 0.15)",
        backgroundColor: "rgb(246, 248, 250)",
        color: "rgb(36, 41, 47)",
        fontFamily: "-apple-system, BlinkMacSystemFont, sans-serif",
        fontWeight: "600",
        lineHeight: "20px",
        fontSize: "14px",
        padding: "5px 16px",
        textAlign: "center",
        cursor: "pointer",
        appearance: "none",
        userSelect: "none",
      }}
    >
      {children}
    </button>
  );
}

export default Button;

 

์ด ์ฝ”๋“œ๋ฅผ ๋‹ค๋ฅธ React์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋ ค๋ฉด?

 

import { Button } from "./Button";

function App() {
  return <Button>Button</Button>;
}

 

๊ทธ๋ ‡๋‹ค๋ฉด , ๋ธŒ๋ผ์šฐ์ €์—์„œ ์†Œ์Šค๋ณด๊ธฐ๋ฅผ ํ•ด๋ณด๋ฉด button์š”์†Œ์— Emotion ์ด ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ค€ ํด๋ž˜์Šค ์ด๋ฆ„์ด ๋ถ™์–ด์žˆ๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

๊ฐ€๋ณ€ ์Šคํƒ€์ผ๋ง(props ์ „์†ก)

 

Emotion์„ ์‚ฌ์šฉํ•˜๋ฉด React ์ปดํฌ๋„ŒํŠธ์— ๋„˜์–ด์˜จ props์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์Šคํƒ€์ผ์„ ์‰ฝ๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ”๊พธ๊ณ  ์‹ถ์€ CSS ์†์„ฑ๊ฐ’์— ์ƒ์ˆ˜ ๋Œ€์‹ ์— prop์— ๋”ฐ๋ผ ๋ณ€ํ•˜๋Š” ๋ณ€์ˆ˜๋ฅผ ํ• ๋‹นํ•ด์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด, <Button/> ์ปดํฌ๋„ŒํŠธ์— variant๋ผ๋Š” prop์„ ์ถ”๊ฐ€ํ•œ ํ›„์—, ์ด prop์— ์–ด๋–ค ๊ฐ’์ด ๋„˜์–ด์˜ค๋А๋ƒ์— ๋”ฐ๋ผ ๊ธ€์ž์ƒ‰์ด ๋ฐ”๋€Œ๋„๋ก ์ฝ”๋“œ๋ฅผ ์งœ๋ณด์•˜๋‹ค.

 

 

/** @jsxImportSource @emotion/react */

const colors = {
  default: "rgb(36, 41, 47)",
  danger: "rgb(207, 34, 46)",
  outline: "rgb(9, 105, 218)",
};

function Button({ children, variant = "default" }) {
  return (
    <button
      css={{
        borderRadius: "6px",
        border: "1px solid rgba(27, 31, 36, 0.15)",
        backgroundColor: "rgb(246, 248, 250)",
        color: colors[variant],
        fontFamily: "-apple-system, BlinkMacSystemFont, sans-serif",
        fontWeight: "600",
        lineHeight: "20px",
        fontSize: "14px",
        padding: "5px 16px",
        textAlign: "center",
        cursor: "pointer",
        appearance: "none",
        userSelect: "none",
      }}
    >
      {children}
    </button>
  );
}

export default Button;
import Button from "./Button";

function App() {
  return (
    <>
      <Button variant="default">Default</Button>
      <Button variant="danger">Danger</Button>
      <Button variant="outline">Outline</Button>
    </>
  );
}

 

์ด์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ button์˜ color๋ฅผ props์ „๋‹ฌ๋กœ ์ƒ‰๋งŒ ๋ณ€๊ฒฝ๊ฐ€๋Šฅํ•˜๊ฒŒ ์ฝ”๋“œ๋ฅผ ์งค ์ˆ˜ ์žˆ๋‹ค.

 

 

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

 

size๋ผ๋Š” prop์— ๋„˜์–ด์˜จ ๊ฐ’์—๋”ฐ๋ผ์„œ ๋ฒ„ํŠผ์˜ ํฌ๊ธฐ๊ฐ€ ๋ฐ”๋€Œ๋„๋ก ํ•ด๋ณด์ž.

 

fontSize์†์„ฑ๊ณผ padding์†์„ฑ์„ ๋‹ค๋ฅด๊ฒŒ ํ•ด๋ณด๊ฒ ๋‹ค.

 

/** @jsxImportSource @emotion/react */

const colors = {
  default: "rgb(36, 41, 47)",
  danger: "rgb(207, 34, 46)",
  outline: "rgb(9, 105, 218)",
};

const sizeStyles = {
  sm: {
    fontSize: "12px",
    padding: "3px 12px",
  },
  md: {
    fontSize: "14px",
    padding: "5px 16px",
  },
  lg: {
    fontSize: "16px",
    padding: "9px 20px",
  },
};

function Button({ children, size = "md", variant = "default" }) {
  return (
    <button
      css={{
        borderRadius: "6px",
        border: "1px solid rgba(27, 31, 36, 0.15)",
        backgroundColor: "rgb(246, 248, 250)",
        color: colors[variant],
        fontFamily: "-apple-system, BlinkMacSystemFont, sans-serif",
        fontWeight: "600",
        lineHeight: "20px",
        ...sizeStyles[size],
        textAlign: "center",
        cursor: "pointer",
        appearance: "none",
        userSelect: "none",
      }}
    >
      {children}
    </button>
  );
}

export default Button;
import Button from "./Button";

function App() {
  return (
    <>
      <Button size="sm" variant="default">
        Default
      </Button>
      <Button size="md" variant="default">
        Default
      </Button>
      <Button size="lg" variant="default">
        Default
      </Button>
      <hr />
      <Button size="sm" variant="danger">
        Danger
      </Button>
      <Button size="md" variant="danger">
        Danger
      </Button>
      <Button size="lg" variant="danger">
        Danger
      </Button>
      <hr />
      <Button size="sm" variant="outline">
        Outline
      </Button>
      <Button size="md" variant="outline">
        Outline
      </Button>
      <Button size="lg" variant="outline">
        Outline
      </Button>
    </>
  );
}

 

3๊ฐ€์ง€ ํฌ๊ธฐ์˜ 3๊ฐ€์ง€ ์ƒ‰์ƒ, ์ด 9๊ฐ€์ง€ ์ข…๋ฅ˜์˜ ๋ฒ„ํŠผ์„ ๋งŒ๋“ค์–ด ๋‚ผ ์ˆ˜ ์žˆ๋‹ค.