๐ŸŽจ Frontend/React

๐Ÿ”ฎ React - 9. ์ปดํฌ๋„ŒํŠธ ์Šคํƒ€์ผ๋ง

kongmi 2023. 4. 18. 18:07

๋ฆฌ์•กํŠธ์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์Šคํƒ€์ผ๋ง ํ•  ๋•Œ๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํšŒ์‚ฌ๋งˆ๋‹ค ์š”๊ตฌํ•˜๋Š” ๋ฐฉ์‹์ด ๋‹ค๋ฅด๊ณ  ๊ฐœ๋ฐœ์ž๋งˆ๋‹ค ๊ฐ์ž ์ทจํ–ฅ์— ๋”ฐ๋ผ ์„ ํƒํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์Šคํƒ€์ผ๋ง ๋ฐฉ์‹

  • ์ผ๋ฐ˜ CSS : ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ์‹
  • Sass : ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” CSS ์ „์ฒ˜๋ฆฌ๊ธฐ ์ค‘ ํ•˜๋‚˜๋กœ ํ™•์žฅ๋œ CSS ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ CSS ์ฝ”๋“œ๋ฅผ ๋”์šฑ ์‰ฝ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ค๋‹ˆ๋‹ค.
  • CSS Module : ์Šคํƒ€์ผ์„ ์ž‘์„ฑํ•  ๋•Œ CSS ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฅธ CSS ํด๋ž˜์Šค์˜ ์ด๋ฆ„๊ณผ ์ ˆ๋Œ€ ์ถฉ๋Œํ•˜์ง€ ์•Š๋„๋ก ํŒŒ์ผ๋งˆ๋‹ค ๊ณ ์œ ํ•œ ์ด๋ฆ„์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด ์ฃผ๋Š” ์˜ต์…˜ ์ž…๋‹ˆ๋‹ค.
  • styled-components : ์Šคํƒ€์ผ์„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์— ๋‚ด์žฅ์‹œํ‚ค๋Š” ๋ฐฉ์‹์œผ๋กœ ์Šคํƒ€์ผ์„ ์ž‘์„ฑํ•จ๊ณผ ๋™์‹œ์— ํ•ด๋‹น ์Šคํƒ€์ผ์ด ์ ์šฉ๋œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

๐Ÿ”ฎ ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

$ yarn create react-app [ํด๋”๋ช…]

$ cd [ํด๋”๋ช…]

$ yarn start

Sass ์‚ฌ์šฉํ•˜๊ธฐ

$ yarn add sass

  • Sass๋Š” .sass์™€ .scss ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
  • SCSS๋Š” Sass์˜ 3๋ฒ„์ „ ์ดํ›„ ์ถ”๊ฐ€๋œ ๋ฌธ๋ฒ•์œผ๋กœ์„œ, CSS์™€์˜ ํ˜ธํ™˜์„ฑ์ด ๋” ๋†’์Šต๋‹ˆ๋‹ค.
  • SCSS๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ .scss ํ™•์žฅ์ž๋ฅผ ๊ฐ€์ง€๋ฉฐ, ์ค‘๊ด„ํ˜ธ{ }์™€ ์„ธ๋ฏธ์ฝœ๋ก (;)์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฆฌ์•กํŠธ์—์„œ SCSS๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๊ด€๋ จ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•˜๊ณ , import ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ SCSS ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์™€์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
import React from "react";
import "./0418_1_style.scss"

const MyComponent = () => {

  return (
    <div className="my-component">
      <h1 className="title">์•ˆ๋…•ํ•˜์„ธ์š”. ๋ฆฌ์•กํŠธ ์„ธ์ƒ์— ์˜ค์‹  ๊ฒƒ์„ ํ™˜์˜ ํ•ฉ๋‹ˆ๋‹ค.</h1>
    </div>
  );
}

export default MyComponent;
$primary-color: #007bff;

.my-component {
  background-color: $primary-color;
}

.title {
  font-size: 2em;
  color: #fff;
}

์‘์šฉ ์˜ˆ์ œ

import React from "react";
import "./0418_2_SassComponent.scss"

const SassComponent = () => {

  return (
    <div className="SassComponent">
        <div className="box red"></div>
        <div className="box orange"></div>
        <div className="box yellow"></div>
        <div className="box green"></div>
        <div className="box blue"></div>
        <div className="box navy"></div>
        <div className="box purple"></div>
    </div>
  );
}

export default SassComponent;
@import "./styles/utils.scss";

.SassComponent {
  display: flex;
  // .SassComponent .box ์™€ ๊ฐ™์Œ!!
  .box {
    background: red;
    cursor: pointer;
    transition: all 0.3s ease-in;
    
    // .box์™€ .red๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์˜๋ฏธ
    &.red {
      background: $red;
      @include square(1);
    }
    &.orange {
      background: $orange;
      @include square(2);
    }
    &.yellow {
      background: $yellow;
      @include square(3);
    }
    &.green {
      background: $green;
      @include square(4);
    }
    &.blue {
      background: $blue;
      @include square(5);
    }
    &.navy {
      background: $navy;
      @include square(6);
    }
    &.purple {
      background: $purple;
      @include square(7);
    }
  }
}

utils ํ•จ์ˆ˜ ๋ถ„๋ฆฌํ•˜๊ธฐ

์—ฌ๋Ÿฌ ํŒŒ์ผ์—์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š” Sass ๋ณ€์ˆ˜ ๋ฐ ๋ฏน์Šค์ธ์€ ๋‹ค๋ฅธ ํŒŒ์ผ๋กœ ๋”ฐ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ์ž‘์„ฑํ•œ ๋’ค ํ•„์š”ํ•œ ๊ณณ์—์„œ ์‰ฝ๊ฒŒ ๋ถˆ๋Ÿฌ์™€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@import

src/styles/utils.scss

$red: #fa5252;
$orange: #fd7e14;
$yellow: #fcc419;
$green: #40c057;
$blue: #339af0;
$navy: #5c7cfa;
$purple: #7950f2;

// ๋ฏน์Šค์ธ ๋งŒ๋“ค๊ธฐ : ์žฌ์‚ฌ์šฉ๋˜๋Š” ์Šคํƒ€์ผ ๋ธ”๋ก์„ ํ•จ์ˆ˜์ฒ˜๋Ÿผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉ
@mixin square($size) {
  $calculator: 32px * $size;
  width: $calculator;
  height: $calculator;
}

SassComponent.scss

@import "./styles/utils.scss";

.SassComponent {
  display: flex;
  // .SassComponent .box ์™€ ๊ฐ™์Œ!!
  .box {
    background: red;
    cursor: pointer;
    transition: all 0.3s ease-in;
    
    // .box์™€ .red๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์˜๋ฏธ
    &.red {
      background: $red;
      @include square(1);
    }
    &.orange {
      background: $orange;
      @include square(2);
    }
    &.yellow {
      background: $yellow;
      @include square(3);
    }
    &.green {
      background: $green;
      @include square(4);
    }
    &.blue {
      background: $blue;
      @include square(5);
    }
    &.navy {
      background: $navy;
      @include square(6);
    }
    &.purple {
      background: $purple;
      @include square(7);
    }
  }
}

styled-components

  • ์ตœ๊ทผ ๋งŽ์ด ์“ฐ์ด๋Š” ๋ฐฉ์‹์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ ์•ˆ์— ์Šคํƒ€์ผ์„ ์„ ์–ธํ•˜๋Š” ๋ฐฉ์‹ ์ž…๋‹ˆ๋‹ค.
  • ์ด ๋ฐฉ์‹์„ CSS-in-JS๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

$ yarn add styled-components

  • styled-components์™€ ์ผ๋ฐ˜ className์„ ์‚ฌ์šฉํ•˜๋Š” CSS/Sass๋ฅผ ๋น„๊ตํ–ˆ์„ ๋•Œ,
    style-components์˜ ๊ฐ€์žฅ ํฐ ์žฅ์ ์€ props ๊ฐ’์œผ๋กœ ์ „๋‹ฌ ํ•ด์ฃผ๋Š” ๊ฐ’์„ ์‰ฝ๊ฒŒ ์Šคํƒ€์ผ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.
import styled, { css } from "styled-components";

const Box = styled.div`
  background: ${(props) => props.color || "blue"};
  padding: 1rem;
  display: flex;
  width: 1024px;
  margin: 0 auto;
  /* ์ตœ๋Œ€ ๋„ˆ๋น„๊ฐ€ 1024px ์ผ ๋•Œ, 768px๋กœ ๋ณ€๊ฒฝ */
  @media (max-width: 1024px) {
    width: 768px;
  }
  @media (max-width: 768px) {
    width: 90%;
  }
`;

const Button = styled.button`
  background: #fff;
  color: #000;
  border-radius: 4px;
  padding: 0.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  font-size: 1rem;
  font-weight: 600;
  &:hover {
    background: rgba(255, 255, 255, 0.9);
  }
  ${(props) =>
    props.inverted &&
    css`
      background: none;
      border: 2px solid #fff;
      color: #fff;
      &:hover {
        background: #fff;
        color: #000;
      }
    `};
    & + button {
      margin-left: 2rem;
    }
`;

const StyledComponent = () => {
  return (
    <Box color="orangered">
      <Button>์•ˆ๋…•ํ•˜์„ธ์š”.</Button>
      <Button inverted={true}>ํ…Œ๋‘๋ฆฌ๋งŒ..</Button>
    </Box>
  );
};

export default StyledComponent;