๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

react

React / ์Šคํƒ€์ผ๋ง (2) - Styled Components

CDD (Component Driven Development) : ํ™”๋ฉด์„ ๋…๋ฆฝ์ ์ด๊ณ  ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ตฌ์„ฑํ•˜์—ฌ ๊ฐœ๋ฐœํ•˜๋Š” ๋ฐฉ๋ฒ•๋ก 

 

๋ฆฌ์•กํŠธ๋Š” CDD๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค. ๊ทธ๋ž˜์„œ js ์•ˆ์— html์„ ๋„ฃ์–ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์—ˆ๋Š”๋ฐ, Styled Components๋Š” css๋„ ํฌํ•จํ•ด์„œ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ตฌ์„ฑํ•ด ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ค€๋‹ค.

 

 

Styled Components

CSS-in-JS ๋ฐฉ์‹(css ๋‚ด์šฉ๋„ javascript ์•ˆ์—์„œ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ)์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, ์Šคํƒ€์ผ์„ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

 

 

Styled Components์˜ ์žฅ๋‹จ์ 

์žฅ์ 

  • CSS๋„ ์ปดํฌ๋„ŒํŠธํ™” ํ•  ์ˆ˜ ์žˆ์Œ
  • CSS์™€ JS์˜ ์ƒํ˜ธ์ž‘์šฉ์ด ์‰ฌ์›€ (์•„๋ฌด๋ž˜๋„ ๊ฐ™์€ ํŒŒ์ผ์—์„œ ์ž‘์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์—)
  • Class์˜ ์ด๋ฆ„์„ ์ž๋™์œผ๋กœ ์ง€์–ด์คŒ

๋‹จ์ 

  • ๊ฒฐ๊ตญ์—๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ƒ์„ฑํ•ด์•ผ ์Šคํƒ€์ผ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Javascript์˜ ํฌ๊ธฐ๊ฐ€ ๋ฌด๊ฑฐ์›Œ์ง
  • ์Šคํƒ€์ผ์ด ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง ์‹œ์ ์—์„œ ์ ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ Œ๋”๋ง ์„ฑ๋Šฅ์ด ์ €ํ•˜๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Œ
  • Class ์ด๋ฆ„์ด ์•Œ์•„๋ณด๊ธฐ ํž˜๋“ฆ

 

 


 

 

์‚ฌ์šฉ ์ค€๋น„

์„ค์น˜

npm install styled-components

 

๋ถˆ๋Ÿฌ์˜ค๊ธฐ

styled components๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ์œ„์น˜์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด importํ•œ๋‹ค.

import styled from "styled-components"

 

์ต์Šคํ…์…˜

styled component๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ css ์†์„ฑ ๋“ฑ์„ ์ž๋™์™„์„ฑ ์‹œ์ผœ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋” ํŽธ๋ฆฌํ•˜๋‹ค.

https://marketplace.visualstudio.com/items/?itemName=styled-components.vscode-styled-components

 

vscode-styled-components - Visual Studio Marketplace

Extension for Visual Studio Code - Syntax highlighting for styled-components

marketplace.visualstudio.com

 

 


 

 

์‚ฌ์šฉ ๋ฐฉ๋ฒ•

1. ์ปดํฌ๋„ŒํŠธ ๋งŒ๋“ค๊ธฐ

const ์ปดํฌ๋„ŒํŠธ = styled.ํƒœ๊ทธ์ข…๋ฅ˜`
  css์†์„ฑ1 : ์†์„ฑ๊ฐ’;
  css์†์„ฑ2 : ์†์„ฑ๊ฐ’;
`

 

 

์˜ˆ์‹œ 1 

 

๊ฐ„๋‹จํ•˜๊ฒŒ ์ƒ๊ธด ํŒŒ๋ž€์ƒ‰ ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

 

App.jsx

const BlueButton = styled.button`
  background-color: blue;
  color: white;
  border-radius: 8px;
  border: 1px solid transparent;
  padding: 0.6em 1.2em;
  font-weight: 500;
  cursor: pointer;
`;

function App() {
  return (
    <>
      <div>hello</div>
      <BlueButton>ํŒŒ๋ž€ ๋ฒ„ํŠผ</BlueButton>
    </>
  );
}

 

 

 

์˜ˆ์‹œ 2

 

์ด๋ฒˆ์—๋Š” ์ž์‹ ์š”์†Œ๋“ค์„ ์ˆ˜์ง/์ˆ˜ํ‰ ๊ฐ€์šด๋ฐ๋กœ ์ •๋ ฌํ•˜๋Š” ๋ถ€๋ชจ์š”์†Œ Container ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

 

App.jsx

const Container = styled.div`
  width: 100vw;
  height: 100vh;
  display: grid;
  place-items: center;
`;

function App() {
  return (
    <Container>
      <div>hello</div>
      <BlueButton>ํŒŒ๋ž€ ๋ฒ„ํŠผ</BlueButton>
    </Container>
  );
}

 

 

 


 

 

2. ์ปดํฌ๋„ŒํŠธ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ

const ์ปดํฌ๋„ŒํŠธ = styled(์žฌ์‚ฌ์šฉํ•  ์ปดํฌ๋„ŒํŠธ)`
  ์ถ”๊ฐ€ํ•  css์†์„ฑ1 : ์†์„ฑ๊ฐ’;
  ์ถ”๊ฐ€ํ•  css์†์„ฑ2 : ์†์„ฑ๊ฐ’;
`

 

 

์˜ˆ์‹œ 

 

App.jsx

 

์ฒ˜์Œ์— ๋งŒ๋“  ํŒŒ๋ž€ ๋ฒ„ํŠผ์„ ์ƒ์†๋ฐ›์•„ ํฐ ํŒŒ๋ž€ ๋ฒ„ํŠผ์˜ ์Šคํƒ€์ผ์„ ๊ฐ€์ง„ LargeBlueButton ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

const LargeBlueButton = styled(BlueButton)`
  font-size: 2em;
  padding: 2em 3em;
`;

function App() {
  return (
    <Container>
      <div>hello</div>
      <BlueButton>ํŒŒ๋ž€ ๋ฒ„ํŠผ</BlueButton>
      <LargeBlueButton>ํฐ ํŒŒ๋ž€ ๋ฒ„ํŠผ</LargeBlueButton>
    </Container>
  );
}

 

 

 

 

 

+

 

 

๊ฐœ๋ฐœ์ž ๋„๊ตฌ์˜ Elements ํƒญ์„ ํ™•์ธํ•ด๋ณด๋ฉด ์ž‘์„ฑํ–ˆ๋˜ ์ปดํฌ๋„ŒํŠธ๋“ค์—๊ฒŒ ์ž๋™์œผ๋กœ ํด๋ž˜์Šค๋ช…์ด ์ƒ์„ฑ๋˜์–ด์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋Š” styled components์—์„œ ๋‚ด๊ฐ€ ์ปดํฌ๋„ŒํŠธ์— ์ž‘์„ฑํ•œ ์Šคํƒ€์ผ ๋‚ด์šฉ๋“ค์„ css๋กœ ์ ์šฉ์‹œํ‚ฌ ๋•Œ, ์ž์ฒด์ ์œผ๋กœ ์ž„์˜์˜ ํด๋ž˜์Šค๋ช…์„ ์ƒ์„ฑํ•ด ์„ค์ •ํ•ด์ฃผ๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. 

 

 

 


 

 

3. Props ์‚ฌ์šฉํ•˜๊ธฐ

const ์ปดํฌ๋„ŒํŠธ์ด๋ฆ„ = styled.ํƒœ๊ทธ์ข…๋ฅ˜`
  css์†์„ฑ : ${props => ํ•จ์ˆ˜ ์ฝ”๋“œ}
`

 

 

์˜ˆ์‹œ 1

 

props๋กœ ์•„๋ฌด ๊ฐ’๋„ ์ „๋‹ฌํ•˜์ง€ ์•Š์•˜์„ ๋•Œ๋Š” ๊ธฐ๋ณธ๊ฐ’ 'black'์ด ์„ค์ •๋˜๊ณ  ์žˆ๋‹ค.

const PropsButton = styled.button`
  background-color: ${(props) => props.backgroundColor || 'black'};
`;

function App() {
  return (
    <Container>
      <PropsButton>Props ๋ฒ„ํŠผ</PropsButton>
    </Container>
  );
}

 

 

 

์ด์ œ props๋กœ ๋ฐฐ๊ฒฝ ์ƒ‰์ƒ ๊ฐ’์„ ์ „๋‹ฌํ•˜๋ฉด ์ž˜ ์ ์šฉ์ด ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

const PropsButton = styled.button`
  background-color: ${(props) => props.backgroundColor || 'black'};
`;

function App() {
  return (
    <Container>
      <div>hello</div>
      <BlueButton>ํŒŒ๋ž€ ๋ฒ„ํŠผ</BlueButton>
      <PropsButton backgroundColor="green">Props ๋ฒ„ํŠผ</PropsButton>
    </Container>
  );
}

 

 

 

 

๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋‹ค๋ฅธ ์†์„ฑ๋“ค๋„ ๋” ์ถ”๊ฐ€ํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

const PropsButton = styled.button`
  background-color: ${(props) => props.backgroundColor || 'black'};
  color: ${(props) => props.color || 'white'};
  border: ${(props) => props.border || 'none'};
  border-radius: ${(props) => props.radius || '0'};
  padding: ${(props) => props.padding || '0'};
  width: ${(props) => props.width || 'auto'};
  font-size: ${(props) => props.fontSize || 'auto'};
  font-weight: ${(props) => props.fontWeight || 'auto'};
`;

function App() {
  return (
    <Container>
      <div>hello</div>
      <BlueButton>ํŒŒ๋ž€ ๋ฒ„ํŠผ</BlueButton>
      <PropsButton
        backgroundColor="green"
        color="black"
        border="1px solid black"
        padding="10px">
        Props ๋ฒ„ํŠผ
      </PropsButton>
    </Container>
  );
}

 

 

 

์˜ˆ์‹œ 2

 

์ด๋ฅผ ์‘์šฉํ•ด์„œ rgba()ํ•จ์ˆ˜ ๋‚ด์˜ ๊ฐ ๊ฐ’์„ props๋กœ ๋ฐ›์•„์™€ ํ™”๋ฉด์— ๋ Œ๋”๋งํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

const BackgroundColorDiv = styled.div`
  width: 300px;
  height: 100px;
  background-color: rgba(
    ${(props) => props.input1},
    ${(props) => props.input2},
    ${(props) => props.input3},
    ${(props) => props.input4}
  );
`;

function App() {
  const [input1, setInput1] = useState(0);
  const [input2, setInput2] = useState(0);
  const [input3, setInput3] = useState(0);
  const [input4, setInput4] = useState(0);

  return (
    <Container>
      <input
        type="range"
        value={input1}
        onChange={(e) => setInput1(e.target.value)}
        min={0}
        max={255}
      />
      <span>{input1}</span>
      <input
        type="range"
        value={input2}
        onChange={(e) => setInput2(e.target.value)}
        min={0}
        max={255}
      />
      <span>{input2}</span>
      <input
        type="range"
        value={input3}
        onChange={(e) => setInput3(e.target.value)}
        min={0}
        max={255}
      />
      <span>{input3}</span>
      <input
        type="range"
        value={input4}
        onChange={(e) => setInput4(e.target.value)}
        min={0}
        max={1}
        step={0.01}
      />
      <span>{input4}</span>
      <BackgroundColorDiv
        input1={input1}
        input2={input2}
        input3={input3}
        input4={input4}
      />
    </Container>
  );
}

 

 

์‹คํ–‰ ํ™”๋ฉด์—์„œ๋Š” gif์˜ ์ด๋ฏธ์ง€ ๋†’์ด๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด Container ์ปดํฌ๋„ŒํŠธ์˜ ์ž ์‹œ height๋ฅผ ์—†์•ด๋‹ค..

 

 

Container ์ปดํฌ๋„ŒํŠธ์— backgroundColor์— props๊ฐ’๋“ค์„ ์„ค์ •ํ•ด๋‘๋ฉด ๋ฐฐ๊ฒฝ ์ƒ‰๊น” ์ „์ฒด๊ฐ€ ๋ฐ”๋€Œ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

const Container = styled.div`
  width: 100vw;
  height: 100vh;
  display: grid;
  place-items: center;
  background-color: rgba(
    ${(props) => props.input1},
    ${(props) => props.input2},
    ${(props) => props.input3},
    ${(props) => props.input4}
  );
`;

function App() {
  const [input1, setInput1] = useState(0);
  const [input2, setInput2] = useState(0);
  const [input3, setInput3] = useState(0);
  const [input4, setInput4] = useState(0);

  return (
    <Container input1={input1} input2={input2} input3={input3} input4={input4}>
      {/* input์€ ์œ„์™€ ๋™์ผํ•˜๋ฏ€๋กœ ์ƒ๋žต */}
    </Container>
  );
}

export default App;

 

 

 

 


 

 

4. ์ „์—ญ ์Šคํƒ€์ผ ์„ค์ •ํ•˜๊ธฐ

// import ํ•˜๊ธฐ
import {createGlobalStyle} from "styled-components"

// ์ตœ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์— ๊ฐ€์ ธ๋‹ค ์‚ฌ์šฉ
const GlobalStyle = createGlobalStyle`
  ์ „์—ญcss์†์„ฑ1 : ์†์„ฑ๊ฐ’;
  ์ „์—ญcss์†์„ฑ2 : ์†์„ฑ๊ฐ’;
`

 

 

์ „์—ญ ์Šคํƒ€์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

cssํŒŒ์ผ์— ๊ตณ์ด ๋”ฐ๋กœ ์ž‘์„ฑํ•˜์ง€ ์•Š๋”๋ผ๋„ ์ตœ์ƒ๋‹จ ์ปดํฌ๋„ŒํŠธ์ธ App์—์„œ GlobalStyle์„ ์„ค์ • ํ›„ ๋ถˆ๋Ÿฌ์˜ค๋ฉด ๋™์ผํ•œ ํšจ๊ณผ๋ฅผ ๋‚ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ,

scss์˜ ๋ณ€์ˆ˜๋‚˜ ๋ฏน์Šค์ธ์€ ์ง€์›ํ•˜์ง€ ์•Š์ง€๋งŒ, (์ด๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์ถฉ๋ถ„ํžˆ ์ปค๋ฒ„๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.) ์ค‘์ฒฉ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

const GlobalStyle = createGlobalStyle`
  * {
    margin : 0;
    padding : 0;
  }

  input {
    width : 90%;
  }
`;

function App() {
  const [input1, setInput1] = useState(0);
  const [input2, setInput2] = useState(0);
  const [input3, setInput3] = useState(0);
  const [input4, setInput4] = useState(0);

  return (
    <>
      <GlobalStyle />
      <Container>
        {/* ์ค‘๋žต */}
      </Container>
    </>
  );
}

 

 

 

 

์ฐธ๊ณ 
https://www.samsungsds.com/kr/insights/web_component.html
https://www.elancer.co.kr/blog/detail/290

 

 

'react' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

React / Todo-List ๋งŒ๋“ค๊ธฐ (2)  (0) 2025.04.17
React / ์Šคํƒ€์ผ๋ง (3) - tailwindcss  (0) 2025.04.17
React / ์Šคํƒ€์ผ๋ง (1) - SCSS  (0) 2025.04.15
React / custom Hook  (1) 2025.04.11
React / useRef  (0) 2025.04.11