๐ŸณReact | styled-components ์‚ฌ์šฉํ•˜๊ธฐ

์›์˜ยท2023๋…„ 7์›” 11์ผ
1

์ƒˆ๋กœ์šด ์ง€์‹๐Ÿ’ก

๋ชฉ๋ก ๋ณด๊ธฐ
9/15
post-thumbnail

๐Ÿง์ƒํ™ฉ

๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ์Šคํƒ€์ผ๋ง์„ ํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ์ƒํ™ฉ์— ๋”ฐ๋ผ ๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ์— ๋‹ค๋ฅธ ์Šคํƒ€์ผ ๊ฐ’์„ ์ ์šฉํ•ด์•ผ ํ–ˆ๋‹ค.
๋กœ๊ทธ์ธ input์ฐฝ์˜ border-bottom ์ƒ‰์ƒ์„ ํ‰์†Œ์—๋Š” ํšŒ์ƒ‰, focus ์ผ๋•Œ๋Š” ์ดˆ๋ก์ƒ‰, ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ํ†ต๊ณผ๋ฅผ ์‹คํŒจํ•˜๋ฉด ๋นจ๊ฐ„์ƒ‰์œผ๋กœ ์ง€์ •ํ•˜๊ณ  ์‹ถ์—ˆ๋‹คโ—
focus์ผ ๋•Œ ์ดˆ๋ก์ƒ‰์„ ์ฃผ๋Š”๊ฑด ๊ฐ„๋‹จํžˆ ํ•ด๊ฒฐํ–ˆ์ง€๋งŒ, ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ํ†ต๊ณผ ์—ฌ๋ถ€์— ๋”ฐ๋ผ์„œ ์ถ”๊ฐ€์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ์–ด๋–ป๊ฒŒ ์ƒ‰์ƒ์„ ๋‹ค๋ฅด๊ฒŒ ์ค„์ง€ ๊ณ ๋ฏผํ•˜๋‹ค๊ฐ€ sytled-components๋ฅผ ํ†ตํ•ด ํ•ด๊ฒฐํ–ˆ๋‹ค.๐Ÿคฉ๐Ÿ‘๐Ÿป


๐Ÿ”Žstyled-components

  • React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ style์„ ๋„์™€์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•ด style์„ ์ž‘์„ฑํ•˜๋ฉด, ๊ณ ์œ ํ•œ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์ƒ์„ฑํ•˜์—ฌ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์— ์ ์šฉ๋จ

  • ์ปดํฌ๋„ŒํŠธ ๊ฐ„์˜ style ์žฌ์‚ฌ์šฉ์„ฑ์ด ๋†’์•„์ง€๊ณ  ์ฝ”๋“œ ์ค‘๋ณต ์ค„์ผ ์ˆ˜ ์žˆ์Œ

  • ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑํ•˜๊ณ  ๋ฐฑํ‹ฑ( ` ) ์•ˆ์— CSS ์†์„ฑ ์ž‘์„ฑ
    ์†์„ฑ์— ๋ณ€์ˆ˜ ํฌํ•จ ๊ฐ€๋Šฅ
    props ํ†ตํ•œ ์กฐ๊ฑด๋ถ€๋กœ ๋™์  ์Šคํƒ€์ผ ์ ์šฉ ๊ฐ€๋Šฅ


๐Ÿ’กstyled-components ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

1. styled-components ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜, ์‚ฌ์šฉํ•  ํŒŒ์ผ์—์„œ import

  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜
npm install styled-components
  • ์‚ฌ์šฉํ•  ํŒŒ์ผ์—์„œ import
import React from "react";
import styled from "styled-components";

2. styled ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ HTML ํƒœ๊ทธ ์„ ํƒ, ๋ฐฑํ‹ฑ( ` ) ์•ˆ์— CSS ์Šคํƒ€์ผ์„ ์ž‘์„ฑ

  • ์Šคํƒ€์ผ ์ปดํฌ๋„ŒํŠธ์˜ ์ด๋ฆ„์€ ๋Œ€๋ฌธ์ž๋กœ ์‹œ์ž‘
const Title = styled.h1`
  color: blue;
  margin-top: 1em;
`;

3. JSX์—์„œ ์‚ฌ์šฉ

export default function App() {
  return <Title>Hello World!</Title>;
}

๐Ÿ’กstyle ์ปดํฌ๋„ŒํŠธ ์žฌ์‚ฌ์šฉ์œผ๋กœ ์ฝ”๋“œ ์ค„์ด๊ธฐ

  • ์ค‘๋ณต๋˜๋Š” style์„ ์ปดํฌ๋„ŒํŠธ๋กœ ๋”ฐ๋กœ ๋นผ์„œ ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด ๋ฌธ๋ฒ•์œผ๋กœ ์ ์šฉํ•˜๊ธฐ

์˜ˆ์‹œ

  • ๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ๋•Œ ๊ณตํ†ต๋œ ์Šคํƒ€์ผ์€ ProfileCommonStyle๋กœ ๋”ฐ๋กœ ๋นผ๊ณ ,
    ๊ฐ๊ฐ์˜ ์Šคํƒ€์ผ ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ฐ€์ ธ์™€ ์ ์šฉ
    ์ „์ฒด ์ฝ”๋“œ ๋ณด๋Ÿฌ๊ฐ€๊ธฐ
// ๊ณตํ†ต๋œ ์Šคํƒ€์ผ
const ProfileCommonStyle = css`
  vertical-align: top;
  border-radius: 50%;
  object-fit: cover;
`;


// ๊ณตํ†ต ์Šคํƒ€์ผ ์ปดํฌ๋„ŒํŠธ ๊ฐ€์ ธ์™€ ์ ์šฉํ•˜๊ธฐ
const ProfileLgStyle = styled.img`
  ${ProfileCommonStyle}
  width: 110px;
  height: 110px;
`;

const ProfileMdStyle = styled.img`
  ${ProfileCommonStyle}
  width: 50px;
  height: 50px;
`;

๐Ÿ’กprops ํ†ตํ•ด ํšจ์œจ์ ์œผ๋กœ style ์ฃผ๊ธฐ

  • props ํ†ตํ•ด ์กฐ๊ฑด๋ถ€๋กœ ๋™์  style ์ ์šฉํ•˜๊ธฐ

์˜ˆ์‹œ

  • input์ฐฝ์˜ border-bottom ์ƒ‰๊น”์„ ํŠน์ • ์กฐ๊ฑด(์ƒํƒœ)์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ
    props๋กœ ์ƒํƒœ ์ „๋‹ฌ ํ›„ ๊ทธ์— ๋งž๊ฒŒ style ์ง€์ •
    ์ „์ฒด ์ฝ”๋“œ ๋ณด๋Ÿฌ๊ฐ€๊ธฐ
export function Input(props) {

  return (
    <>
      <label htmlFor={props.id}>{props.label}</label>
  	  <InputStyle {...props}></InputStyle>
	</>
  );
}


const InputStyle = styled.input`
  border-bottom: 1px solid ${(props) => (props.valid ? '#DBDBDB' : '#eb5757')};

  &:focus {
    border-bottom: 1px solid ${(props) => (props.valid ? '#1C8A00' : '#eb5757')};
  }
`;
  • ์‚ฌ์šฉ
<Input id={'example1'} type={'text'} label={'์œ ํšจ์„ฑ O'} valid={true} />
<Input id={'example2'} type={'text'} label={'์œ ํšจ์„ฑ X'} valid={false} />
  • ์ ์šฉ
    ๊ฐ™์€ Input ์ปดํฌ๋„ŒํŠธ์˜ props๋กœ valid ๊ฐ’๋งŒ ๋‹ค๋ฅด๊ฒŒ ๋„˜๊ฒจ์ค˜์„œ border-bottm ์ƒ‰์ƒ ์ง€์ •
profile
ํ™”์ดํŒ…~~^ใ…^/

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

๊น”๋”ํ•œ ์ •๋ฆฌ๋„ค์š” ๊ฐ•์˜๋ณด๋‹ค ์ด ๊ธ€๋กœ ๋” ์ดํ•ด๊ฐ€ ์ž˜ ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค ^-^

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ