Custom Component

hyena_leeยท2023๋…„ 2์›” 22์ผ
0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
29/42
post-thumbnail

๐ŸŒŽ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„ ๊ฐœ๋ฐœ ๋ฐ CSS-in-JS ๋ฐฉ๋ฒ•๋ก 

โ–ถ๏ธ CDD (Component Driven Development)

-> ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ ๊ฐœ๋ฐœ
-> ๋‹ค์ˆ˜ CDD ์ง€์› ๋„๊ตฌ ์กด์žฌ
-> ๊ทธ ์ค‘ ํ•˜๋‚˜๊ฐ€ Component Explorer(์ปดํฌ๋„ŒํŠธ ํƒ์ƒ‰๊ธฐ)
-> Component Explorer ์ค‘ ํ•˜๋‚˜๊ฐ€ Storybook

โ–ถ๏ธ ๊ตฌ์กฐ์  CSS ์ž‘์„ฑ ๋ฐฉ๋ฒ•์˜ ๋ฐœ์ „ ๊ณผ์ •

(CSS -> SASS -> BEM -> Styled Components)

โ–ถ๏ธ CSS in JS ๋ฐฉ๋ฒ•๋ก 

-> CDD๋กœ CSS ์ž‘์„ฑ โ€“

๋‹ค์ˆ˜ React ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์กด์žฌ
-> ๊ทธ ์ค‘ ๋Œ€์ค‘์ ์ธ Styled Components

โ–ถ๏ธ CSS ๋ฐฉ๋ฒ•๋ก ๋“ค์˜ ํŠน์ง•, ์žฅ๋‹จ์ 


โ–ถ๏ธstyled-components

๊ธฐ์กด ๋”์„ ๋งŒ๋“œ๋Š” ๋ฐฉ์‹์ธ css, scss ํŒŒ์ผ์„ ๋ฐ–์— ๋‘๊ณ , ํƒœ๊ทธ๋‚˜ id, class์ด๋ฆ„์œผ๋กœ ๊ฐ€์ ธ์™€ ์“ฐ์ง€ ์•Š๊ณ , ๋™์ผํ•œ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„์„ ์“ฐ๋“ฏ ์Šคํƒ€์ผ์„ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์„ styled-components๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.
css ํŒŒ์ผ์„ ๋ฐ–์— ๋‘์ง€ ์•Š๊ณ , ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์— ๋„ฃ๊ธฐ ๋•Œ๋ฌธ์—, css๊ฐ€ ์ „์—ญ์œผ๋กœ ์ค‘์ฒฉ๋˜์ง€ ์•Š๋„๋ก ๋งŒ๋“ค์–ด์ฃผ๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

โ–ถ๏ธstyled components ๋งŒ๋“ค๊ธฐ

const ์ปดํฌ๋„ŒํŠธ๋ช… = styled.ํƒœ๊ทธ๋ช…์Šคํƒ€์ผ ๋„ฃ๊ธฐ...๋ฌธ๋ฒ•์œผ๋กœ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค.
๋งŒ๋“ค๊ณ ์žํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์˜ render ํ•จ์ˆ˜ ๋ฐ–์—์„œ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

โ–ถ๏ธ์Šคํƒ€์ผ์— props ์ ์šฉํ•˜๊ธฐ

styled-component๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์žฅ์  ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ณ€์ˆ˜์— ์˜ํ•ด ์Šคํƒ€์ผ์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค.
์œ„ ์˜ˆ์‹œ๋ฅผ ๋ณด๋ฉด email์ด๋ผ๋Š” state๊ฐ’์— ๋”ฐ๋ผ ExampleWrap์— prop์œผ๋กœ ๋‚ด๋ ค์ค€ active๋ผ๋Š” ๊ฐ’์ด true or false๋กœ ๋ฐ”๋€Œ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
styled-component๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ props์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ณ , ๊ทธ props์— ๋”ฐ๋ผ ์Šคํƒ€์ผ์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
#์Šคํƒ€์ผ

โ–ถ๏ธ์Šคํƒ€์ผ ์ƒ์†

const ์ปดํฌ๋„ŒํŠธ๋ช… = styled.์Šคํƒ€์ผ์ปดํฌ๋„ŒํŠธ๋ช…์Šคํƒ€์ผ ๋„ฃ๊ธฐ...๋ฌธ๋ฒ•์œผ๋กœ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค.
๊ธฐ์กด์— ์žˆ๋Š” ์Šคํƒ€์ผ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ƒ์†๋ฐ›์•„ ์žฌ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

โ–ถ๏ธ Mixin css props


const flexCenter = css`
  display: flex;
  justify-content: center;
  align-items: center;
`;

const FlexBox = div`
  ${flexCenter}
`;

๐ŸŒŽ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ ์ปดํฌ๋„ŒํŠธ import

// Login.jsx
export const LoginContainer = styled.div`
  background: red;
`;

// Other.jsx
import { LoginContainer } from ".Login";

const Other = () => {
  return <LoginContainer>...</LoginContainer>;
};

๐ŸŒ– ๋ฐ˜์‘ํ˜•๋””์ž์ธ

import React from "react";
import styled, { css } from "styled-components";

const sizes = {
  desktop: 1024,
  tablet: 768
};

// sizes ๊ฐ์ฒด์— ๋”ฐ๋ผ ์ž๋™์œผ๋กœ media ์ฟผ๋ฆฌ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.
const media = Object.keys(sizes).reduce((acc, label) => {
  acc[label] = (...args) => css`
    @media (max-width: ${sizes[label] / 16}em) {
      ${css(...args)};
    }
  `;

  return acc;
}, {});

const Box = styled.div`
  /* props ๋กœ ๋„ฃ์–ด์ค€ ๊ฐ’์„ ์ง์ ‘ ์ „๋‹ฌํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. */
  background: ${props => props.color || "blue"};
  padding: 1rem;
  display: flex;
  width: 1024px;
  margin: 0 auto;
  ${media.desktop`width: 768px;`}
  ${media.tablet`width: 768px;`};
`;

๐ŸŒ– global css

import styled, { createGlobalStyle } from "styled-components";

export const GlobalStyle = createGlobalStyle`
  body{padding:0; margin:0}
`;
profile
์‹ค์ˆ˜๋ฅผ ๋‘๋ ค์›Œ ๋ง๊ณ  ๊ณ„์† ๋„์ „ ํ•˜๋Š” ๊ฐœ๋ฐœ์ž์˜ ์—ฌ์ •!

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