[DevCamp] ๐Ÿงฑ ๋ ˆ์ด์•„์›ƒ ๊ตฌ์„ฑ๊ณผ ๊ธ€๋กœ๋ฒŒ ์Šคํƒ€์ผ, ๊ทธ๋ฆฌ๊ณ  Styled-Components

๋™๊ฑดยท2025๋…„ 4์›” 17์ผ

DevCamp

๋ชฉ๋ก ๋ณด๊ธฐ
50/85

๐Ÿงฑ ๋ ˆ์ด์•„์›ƒ ๊ตฌ์„ฑ๊ณผ ๊ธ€๋กœ๋ฒŒ ์Šคํƒ€์ผ, ๊ทธ๋ฆฌ๊ณ  Styled-Components

React ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ตฌ์„ฑํ•  ๋•Œ, ์ปดํฌ๋„ŒํŠธ ํ•˜๋‚˜ํ•˜๋‚˜ ๋งŒ๋“œ๋Š” ๊ฒƒ๋„ ์ค‘์š”ํ•˜์ง€๋งŒ
๋” ์ค‘์š”ํ•œ ๊ฑด ํ™”๋ฉด์˜ ๋ผˆ๋Œ€, ์ฆ‰ ๋ ˆ์ด์•„์›ƒ๊ณผ ์ „์—ญ ์Šคํƒ€์ผ์„ ์ž˜ ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์˜ค๋Š˜์€ ๋ ˆ์ด์•„์›ƒ์˜ ํ•„์š”์„ฑ๊ณผ ํ•จ๊ป˜, ๊ธ€๋กœ๋ฒŒ ์Šคํƒ€์ผ,
๊ทธ๋ฆฌ๊ณ  Styled-Components๋ฅผ ํ™œ์šฉํ•œ ์Šคํƒ€์ผ ๊ด€๋ฆฌ๊นŒ์ง€ ์ •๋ฆฌํ–ˆ๋‹ค.


๐Ÿ“ ๋ ˆ์ด์•„์›ƒ์€ ์™œ ํ•„์š”ํ• ๊นŒ?

๋ ˆ์ด์•„์›ƒ์€ ๋‹จ์ˆœํžˆ UI๋ฅผ ๋ณด๊ธฐ ์ข‹๊ฒŒ ๋‚˜๋ˆ„๊ธฐ ์œ„ํ•œ ๊ฒƒ๋งŒ์ด ์•„๋‹ˆ๋‹ค.
๊ทธ ์ด์ƒ์œผ๋กœ ์ค‘์š”ํ•œ ์—ญํ• ๋“ค์„ ๋งก๋Š”๋‹ค.

  1. ํ”„๋กœ์ ํŠธ์˜ ๊ธฐ๋ณธ์ ์ธ ํ™”๋ฉด ๊ตฌ์กฐ๋ฅผ ์žก์•„์ค€๋‹ค
  2. ๋ชจ๋“  ํ™”๋ฉด์—์„œ ๋ฐ˜๋ณต์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” Header, Footer, Sidebar ๋“ฑ์„ ๊ณ ์ •ํ•ด์„œ ๋ณด์—ฌ์ค€๋‹ค
  3. ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋ ˆ์ด์•„์›ƒ์„ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋ฐ˜์„ ๋งŒ๋“ ๋‹ค (ex. ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ vs ๋Œ€์‹œ๋ณด๋“œ)
// Layout.tsx
const Layout = ({ children }: { children: React.ReactNode }) => {
  return (
    <>
      <Header />
      <main>{children}</main>
      <Footer />
    </>
  );
};

๐Ÿ‘ถ children ์ปดํฌ๋„ŒํŠธ์˜ ํƒ€์ž…

children์—๋Š” ๋‹ค์–‘ํ•œ ํƒ€์ž…์˜ React ์š”์†Œ๊ฐ€ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ์–ด์„œ ์ •ํ™•ํ•œ ํƒ€์ž…์„ ์•„๋Š” ๊ฒŒ ์ค‘์š”ํ•˜๋‹ค.

  • JSX.Element: ํ•˜๋‚˜์˜ JSX๋งŒ ์˜ฌ ์ˆ˜ ์žˆ์Œ
  • ReactElement: JSX.Element์˜ ๋” ์ผ๋ฐ˜์ ์ธ ํ˜•ํƒœ
  • ReactNode: ๋ฌธ์ž์—ด, ์ˆซ์ž, boolean, null, undefined, ReactElement ๋“ฑ ๋Œ€๋ถ€๋ถ„์˜ React์—์„œ ๋ Œ๋” ๊ฐ€๋Šฅํ•œ ์š”์†Œ ํฌํ•จ โ†’ ๋Œ€๋ถ€๋ถ„ ์ด๊ฑธ ์”€
interface LayoutProps {
  children: React.ReactNode;
}

๐ŸŒ Global Style

React ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์ „์—ญ ์Šคํƒ€์ผ(Global Style)์„ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒŒ ์ข‹๋‹ค.
์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค:

  1. ํ”„๋กœ์ ํŠธ ์ „๋ฐ˜์— ๊ฑธ์ณ ์ผ๊ด€๋œ ์Šคํƒ€์ผ ์ ์šฉ์ด ๊ฐ€๋Šฅ
  2. ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ์Šคํƒ€์ผ(User Agent Stylesheet)์˜ ์ฐจ์ด๋ฅผ ์ดˆ๊ธฐํ™”
  3. ํ—ค๋”/ํ‘ธํ„ฐ/๋ฒ„ํŠผ ๋“ฑ์˜ ์Šคํƒ€์ผ์„ ๋ชจ๋“  ํŽ˜์ด์ง€์—์„œ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€

์ „์—ญ ์Šคํƒ€์ผ ์ดˆ๊ธฐํ™” ๋ฐฉ๋ฒ•

์ „ํ†ต์ ์œผ๋กœ๋Š” CSS ์ดˆ๊ธฐํ™” ๋ฐฉ์‹์ด ์•„๋ž˜ ์„ธ ๊ฐ€์ง€๊ฐ€ ๋Œ€ํ‘œ์ ์ด๋‹ค:


๐Ÿ’ก css-in-js๋Š” ์™œ ํ•„์š”ํ• ๊นŒ?

์ „ํ†ต์ ์ธ CSS ๋ฐฉ์‹์€ ํ”„๋กœ์ ํŠธ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค:

  • ์ „์—ญ ๋„ค์ด๋ฐ ์ถฉ๋Œ
  • ๋ถˆํ•„์š”ํ•œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ
  • ์ปดํฌ๋„ŒํŠธ์™€ ์Šคํƒ€์ผ์ด ๋ถ„๋ฆฌ๋˜์–ด ์ถ”์ ํ•˜๊ธฐ ์–ด๋ ค์›€
  • ํŠน์ • ์ปดํฌ๋„ŒํŠธ์—๋งŒ ์“ฐ์ด๋Š” ์Šคํƒ€์ผ๋„ ์ „์—ญ์— ๋กœ๋”ฉ๋จ
  • ๋ช…์‹œ๋„/์šฐ์„ ์ˆœ์œ„ ๋ฌธ์ œ (Specificity)

๊ทธ๋ž˜์„œ ๋‚˜์˜จ ๋ฐฉ์‹์ด CSS-in-JS๋‹ค. ๊ทธ์ค‘ ๋Œ€ํ‘œ์ ์ธ ๊ฒƒ์ด styled-components.


๐ŸŽจ styled-components๋กœ ์Šคํƒ€์ผ ๊ด€๋ฆฌํ•˜๊ธฐ

npm install styled-components
npm install --save-dev @types/styled-components
import styled, { createGlobalStyle } from 'styled-components';

export const GlobalStyle = createGlobalStyle`
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }
  body {
    font-family: 'Pretendard', sans-serif;
    background-color: #121212;
    color: white;
  }
`;

์ „์—ญ ์Šคํƒ€์ผ์„ ํ•œ ๋ฒˆ๋งŒ ์„ค์ •ํ•˜๋ฉด, ์–ด๋–ค ํŽ˜์ด์ง€๋“  ์ผ๊ด€๋œ ์Šคํƒ€์ผ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„๋กœ ์Šคํƒ€์ผ์„ ๋ถ„๋ฆฌํ•ด ์บก์Аํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค:

const StyledButton = styled.button`
  background-color: #5c6bc0;
  color: white;
  padding: 10px 20px;
  border-radius: 8px;
  border: none;
`;

๐Ÿ”จ TIL

  • ๋ ˆ์ด์•„์›ƒ์€ ๋ฐ˜๋ณต ์š”์†Œ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ , ์•ฑ ๊ตฌ์กฐ๋ฅผ ์žก๋Š” ๋ฐ ํ•„์ˆ˜๋‹ค.
  • children์˜ ํƒ€์ž…์€ ReactNode๋ฅผ ์ฃผ๋กœ ์“ด๋‹ค.
  • ์ „์—ญ ์Šคํƒ€์ผ์€ ์Šคํƒ€์ผ ์ผ๊ด€์„ฑ ์œ ์ง€์™€ ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ์Šคํƒ€์ผ ์ดˆ๊ธฐํ™”์— ํ•„์š”ํ•˜๋‹ค.
  • CSS-in-JS ๋ฐฉ์‹ ์ค‘ styled-components๋Š” ์Šคํƒ€์ผ์„ ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ์œ ์ง€๋ณด์ˆ˜์— ์œ ๋ฆฌํ•˜๋‹ค.
profile
๋ฐฐ๊ณ ํ”ˆ ๊ฐœ๋ฐœ์ž

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