React styled-components ์‚ฌ์šฉ

TH_velogยท2023๋…„ 11์›” 16์ผ
0

React

๋ชฉ๋ก ๋ณด๊ธฐ
12/16
post-thumbnail
post-custom-banner

๐Ÿ–‹๏ธ๊ธฐ๋ก์šฉ Velogโœ…
โ€ป ์ž์„ธํ•œ ์„ค๋ช…์€ ๊ตฌ๊ธ€๋ง ๋‹ค๋ฅธ ๋ถ„๋“ค ์ฐธ๊ณ  โœ”๏ธ

๐Ÿ“Œ styled-components

๐Ÿ“– styled-components

css ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  React ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ ์Šคํƒ€์ผ์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š” CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

โœ”๏ธ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์—๋งŒ ์ ์šฉ ๋‹ค๋ฅธ ๊ณณ ์˜ํ–ฅ ๊ฑฑ์ • X
โœ”๏ธ props๋ฅผ ํ™œ์šฉํ•œ ์กฐ๊ฑด๋ถ€ ์‚ฌ์šฉ, ์žฌํ™œ์šฉ
โœ”๏ธ ๋ณ€ํ•˜์ง€ ์•Š๋Š” ๊ณ ์ •๋œ ๊ฐ’ ์ƒ์ˆ˜๋ฅผ ๊ณต์œ ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
โœ”๏ธ ๋„ค์ด๋ฐ์„ ํŽธํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
โœ”๏ธ styled-components ์ปดํฌ๋„ŒํŠธ ๊ตฌ๋ถ„ ๋ฐ ์ถ”์ ์ด ์–ด๋ ต๋‹ค.
โœ”๏ธ ๊ธฐํƒ€ ๋“ฑ ๐Ÿ˜…

๐Ÿ“— styled-components ์„ค์น˜ํ•˜๊ธฐ

 npm install styled-components

๐Ÿ“— ์‚ฌ์šฉ๋ฒ•

โœ”๏ธ import styled
โœ”๏ธ styled components ์ž‘์„ฑ ์‹œ ์ปดํฌ๋„ŒํŠธ์ด๊ธฐ์— ์ฒซ๊ธ€์ž ๋Œ€๋ฌธ์ž!
โœ”๏ธ SCSS ์‚ฌ์šฉํ•˜๋“ฏ์ด ์ž‘์„ฑ ๊ฐ€๋Šฅ.
๐Ÿ‘‰ EX) const StyledComponents = styled.h1

โœ”๏ธ styled.์‚ฌ์šฉํ•  ํƒœ๊ทธ(css ์ ์šฉํ•  ํƒœ๊ทธ)
๐Ÿ‘‰ EX) styled.div / styled.h1

import styled from 'styled-components'

// ๋Œ€๋ฌธ์ž๋กœ ์‹œ์ž‘ํ•˜๋Š” styled components
// styled.์‚ฌ์šฉํ•˜๋Š” ํƒœ๊ทธ`(๋นฝํ‹ฑ๊ธฐํ˜ธ) css ์ž…๋ ฅ `;
const StyledComponents = styled.div` 
 // ๐Ÿ‘‡CSS ์ž‘์„ฑ
  background:#000;
`
function StyledTest(){
 return (
 	<StyledComponents>
   		๋ฐฐ๊ฒฝ์ƒ‰ #000 div ์™„๋ฃŒ!!
 	</StyledComponents>
 )
}
export default StyledTest;

๐Ÿ“— ์ƒ์† / ์žฌํ™œ์šฉ

โœ”๏ธ ๋งŒ๋“ค์–ด ๋†“์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ( ) ๊ด„ํ˜ธ๋กœ ์ƒ์† ๋ฐ›์•„์„œ ์žฌํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import styled from 'styled-components'

const SpanYellow = styled.div`
  background:yellow;
  color:#000;
`;
const Box1 = styled(SpanYellow)`
  width:100px;
  height:100px;
`;
const Box2 = styled(SpanYellow)`
  width:200px;
  height:200px;
  color:red;
`;
const Box3 = styled(SpanYellow)`
  width:200px;
  height:200px;
  background:green;
  color:#fff;
`;

function StyledComponents1 () {
  return (
    <>
      <Box1>Box1 ์ž…๋‹ˆ๋‹ค.</Box1>
      <Box2>Box2 ์ž…๋‹ˆ๋‹ค.</Box2>
      <Box3>Box2 ์ž…๋‹ˆ๋‹ค.</Box3>
    </>
  ) 
}

โœ”๏ธ .์˜จ์  ๋Œ€์‹  ( ) ๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
โœ”๏ธ css๋ฅผ ์ƒ์†๋ฐ›๊ณ  ์ถ”๊ฐ€๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
โœ”๏ธ ๋งŒ์•ฝ ๊ฐ™์€ ์†์„ฑ์„ ์žฌ์ž…๋ ฅํ•  ๊ฒฝ์šฐ ๋ฎ์–ด์”Œ๊ฒŒ ๋œ๋‹ค.

๐Ÿ“— attrs ์†์„ฑ ์ง€์ •

styled.button.attrs({์†์„ฑ})
โœ”๏ธ .attrs๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

EX) ๋ฒ„ํŠผ์˜ ๊ฒฝ์šฐ

const Button1 = styled.button`
	background:#000;
  color:#fff;
`;
// 
<Button1>๋ฒ„ํŠผ์ž…๋‹ˆ๋‹ค.</Button1> 
// โœ….attrs ์‚ฌ์šฉ
const Button2 = styled.button.attrs({
  // ์—ฌ๊ธฐ์— ์†์„ฑ ์ž…๋ ฅ
  type:'button'
})`
  background:#000;
  color:#fff;
`;
//
<Button2>๋ฒ„ํŠผ์ž…๋‹ˆ๋‹ค.</Button2>

โœ”๏ธ โ˜๏ธ์†์„ฑ์„ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“— as ์‚ฌ์šฉํ•˜์—ฌ ํƒœ๊ทธ ๋ณ€๊ฒฝ

โœ”๏ธ styled.์ง€์ •๋œ ํƒœ๊ทธ๋ฅผ ๊ฐ™์€ css ์Šคํƒ€์ผ๋กœ ๋‹ค๋ฅธ ํƒœ๊ทธ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด!?
as="๋ณ€๊ฒฝ ํƒœ๊ทธ"

const BorderBox = styled.div` // div
  width:100px;
  height:100px;
  margin:20px;
  border:1px solid #ddd;
`
const CircleText = styled.p` // p
  &::before {
    content:'\\22C5';
  }
`
/////// 
<BorderBox>
  <CircleText>ํ…์ŠคํŠธ</CircleText>
</BorderBox>
<BorderBox as="ul"> ๐Ÿ‘ˆ ul ๋ณ€๊ฒฝ
  <CircleText as="li"> ๐Ÿ‘ˆ li ๋ณ€๊ฒฝ
    ํ…์ŠคํŠธ
  </CircleText>
</BorderBox>

โœ”๏ธ ๊ฐ™์€ ์Šคํƒ€์ผ๋กœ ํƒœ๊ทธ๋งŒ ๋‹ค๋ฅด๊ฒŒ ์ ์šฉ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“— props

โœ”๏ธ props๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ๋ฐ›์•„ ์‚ฌ์šฉ ๋ฐ ์กฐ๊ฑด์— ๋”ฐ๋ฅธ ์Šคํƒ€์ผ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

// ๊ธฐ๋ณธ ์ž‘์„ฑ๋ฒ•
${props => props.๋ฐ›์•„์˜จ๊ฐ’ }
// ๐Ÿ‘‡ EX) 
color:${props => props.color || #000000 };

โœ…ํ…Œ์ŠคํŠธ

import styled from 'styled-components'

// โœ… props 
// ์ฝ”๋“œ ํ™•์ธ ๋ฐ ๋ณต์‚ฌ์šฉ
const PropsStyled = styled.div`
  margin:20px;
  background:${props => props.bg || 'pink'};
  ${props=> props.border && `
    border: ${props.border};
  `};
  color:${props=> props.color || 'white'};
`
function StyledComponentsTest () {
  return (
    <>
      <PropsStyled>
        ๊ธฐ๋ณธ
      </PropsStyled>
      <PropsStyled color={"green"} bg={"black"}>
        color:black
        background:green
      </PropsStyled>
      <PropsStyled color={"red"} bg={"yellow"} border={"1px solid #000"}>
        color: red
        background:yellow
      </PropsStyled>
    </>
  ) 
}

export default StyledComponentsTest;
${props => props.bg || 'default'}

โœ”๏ธ ||์„ ์‚ฌ์šฉํ•˜์—ฌ props.bg๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ bg ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์—†๋Š” ๊ฒฝ์šฐ์— default ๊ฐ’์„ ์ž…๋ ฅํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
โœ”๏ธ background,color์˜ ๊ฒฝ์šฐ ์ž…๋ ฅ๋œ ์ƒํƒœ์—์„œ props๊ฐ’ ๋˜๋Š” default ๊ฐ’์ด ๋“ค์–ด๊ฐ€๊ฒŒ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค
โœ”๏ธborder์˜ ๊ฒฝ์šฐ props.border ์žˆ๋Š” ๊ฒฝ์šฐ์—๋งŒ border ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โœ”๏ธ ๐Ÿ‘‡๊ฒฐ๊ณผ๋ฌผ

โš ๏ธ color, bgColor ๋“ฑ ๋‹ค๋ฅธ ์ž˜๋ชป๋œ ๋„ค์ด๋ฐ์œผ๋กœ ์ž…๋ ฅ ์‹œ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒฝ๊ณ ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜๋Š” ๐Ÿ‘€

๐Ÿ‘‡ ๊ฒฝ๊ณ ๋ฌธ ํ•ด๊ฒฐ

โš ๏ธ $(prefix) ๋ถ™์—ฌ์„œ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒฝ๊ณ ๋ฌธ์ด ์‚ฌ๋ผ์ง„๋‹ค.

  • $ ์‚ฌ์šฉํ•˜๋ฉด ํ•„ํ„ฐ๋งํ•˜์—ฌ DOM ์š”์†Œ์— ์ „๋‹ฌ๋˜๋Š” ๊ฒƒ์„ ๋ง‰๋Š”๋‹ค.
  • ๋ถˆํ•„์š”ํ•œ ์†์„ฑ ์ „๋‹ฌ์„ ๋ฐฉ์ง€
  • ์Šคํƒ€์ผ๋“œ์ปดํฌ๋„ŒํŠธ์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋„๋ก ๋ช…์‹œ์ ์œผ๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“˜ ์ž์‹์ปดํฌ๋„ŒํŠธ์—๊ฒŒ props ์ „๋‹ฌ ๋ฐ ์‚ฌ์šฉ

// parent.jsx
const ParentWrap = styled.div`
  width:150px;
  height:150px;
  margin:20px;
  border:1px solid #ddd;
`;
function PropsStyledChildren(){
  return (
    <ParentWrap>
      {/* EX) ๐Ÿ‘‡์ž์‹ ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ ๋ฐฐ๊ฒฝ์ƒ‰๊ณผ border ์ „๋‹ฌ */}
      <ChildrenStyled $bg={"blue"} $border={"1px solid green"} /> 
    </ParentWrap>
  )
}

//children.jsx
const ChildrenWrap = styled.div`
  width:100px;
  height:100px;
  margin:20px;
  ${props => `
    ${props.$bg && `background: ${props.$bg};`}
    ${props.$border && `border: ${props.$border};`}
  `}
  color:#fff;
`;
// โœ… ๋ฐฉ๋ฒ• 1 - $bg, $border ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•
function ChildrenStyled({$bg, $border}){
  return (
    <ChildrenWrap $bg={$bg} $border={$border}>
      <p>zz</p>
    </ChildrenWrap>
  )
}

// โœ… ๋ฐฉ๋ฒ• 2 - ...props
function ChildrenStyled({...props}){
  return (
    <ChildrenWrap {...props}>
      <p>TEST</p>
    </ChildrenWrap>
  )
}

โœ… ์ •์ƒ ์ถœ๋ ฅ

๐Ÿ“— GlobalStyle - ์ „์—ญ ์Šคํƒ€์ผ

โœ”๏ธ GlobalStyle ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค๊ณ  importํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.
โœ”๏ธCSS common.css ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๋“ฏ์ด ์‚ฌ์šฉ ๊ฐ€๋Šฅ

โœ… import ํ™•์ธ!

// GolbalStyle.jsx ํŒŒ์ผ ์ƒ์„ฑ
import { createGlobalStyle } from 'styled-components'

// โœ… Global TEST์ž…๋‹ˆ๋‹ค
const GolbalStyle = createGlobalStyle`
  * {margin:0; padding:0}
  .App {
    div {
      width:100px;
      height:100px;
      border:1px solid #ddd;
    }
    p{ 
      font-size:14px;
      color:red;
    }
  }
`;

export default GolbalStyle;

โœ… ๊ธ€๋กœ๋ฒŒ ์Šคํƒ€์ผ ์ ์šฉํ•  ํ…Œ์ŠคํŠธ ์ปดํฌ๋„ŒํŠธ

// StyledGlobalTest.jsx
function StyledGlobalTest (){
  return (
    <div>
      <p>styled components - Global TEST</p>
    </div>
  )

}
export default StyledGlobalTest;
// App.js
function App() {
  return (
    <div className="App">
      <GolbalStyle />
      <StyledGlobalTest />
    </div>
  );
}
โœ… GlobalStyle ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ ๋

โš ๏ธ์œ„์™€ ๊ฐ™์ด ์‚ฌ์šฉ ์‹œ ๊ฒฝ๊ณ ๋ฌธ๊ณผ ํ•จ๊ป˜ ์ ์šฉ์ด ๋˜์ง€ ์•Š๋Š”๋‹ค.

โœ… GobalStyle ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ ์‚ฌ์ด์— ์‚ฌ์šฉํ•ด๋„ ์ •์ƒ๋™์ž‘
css๋ฅผ import ํ•˜๋“ฏ์ด GolbalStyle ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ์‹œ ๋ถ€๋ชจ ์ž์‹ ์ปดํฌ๋„ŒํŠธ ์— ์Šคํƒ€์ผ์ด ์ ์šฉ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธ

๊ธฐ๋ก ๋.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ˜

profile
๊ณต๋ถ€&๊ธฐ๋ก
post-custom-banner

0๊ฐœ์˜ ๋Œ“๊ธ€