๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ—‚ WIL/๐Ÿ“ React

๐Ÿงฌ Atomic ๋””์ž์ธ์„ ์ ์šฉํ•ด๋ณด์ž.

by nalong 2022. 8. 13.

# ์•„ํ† ๋ฏน ๋””์ž์ธ ์™œ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€์ง€?  

ํŒ€ ํ”„๋กœ์ ํŠธ์—์„œ  pages, components ํด๋”๋กœ ๋‚˜๋ˆ„๊ณ  ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋“ค์€ components ํด๋”์—, ํ•ด๋‹น ํŽ˜์ด์ง€์— ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋“ค์€ ํŽ˜์ด์ง€ ํด๋”์—์„œ ๊ด€๋ฆฌํ•˜๋„๋ก ํ•˜์˜€๋‹ค.  ์•„ํ† ๋ฏน ๊ตฌ์กฐ๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ถ์—ˆ์ง€๋งŒ, ์ ์šฉํ•˜์ง€ ๋ชปํ–ˆ๋Š”๋ฐ ๊ทธ ์ด์œ ๋Š”

 

1. ํ”ผ๊ทธ๋งˆ๊ฐ€ ์™„๋ฒฝํžˆ ๋˜์ง€ ์•Š์€ ์ƒํƒœ, ๊ทธ๋ฆฌ๊ณ  ๊ณ„์† ๊ตฌํ˜„ํ•˜๋ฉด์„œ ๋ณ€๊ฒฝ๋  ํ™•๋ฅ ์ด ๋†’์Œ.

-> ์ž˜๊ฒŒ ์ชผ๊ฐœ๋Š” ๋ฐฉ์‹์ธ ์•„ํ† ๋ฏน ๊ตฌ์กฐ๋ฅผ ์ ์šฉํ•˜๊ธฐ์—๋Š” ์–ด๋ ค์›€์ด ์ƒ๊ธธ ๊ฒƒ ๊ฐ™์€ ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

2. ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ๊ฐ€ ์•„๋‹Œ ํŒ€ ํ”„๋กœ์ ํŠธ, ์ •ํ•ด์ง„ ๊ธฐ๊ฐ„ ๋‚ด์— ํ”„๋กœ์ ํŠธ ๋งˆ๋ฌด๋ฆฌ.

-> ๊ตฌ์กฐ์ ์ธ ์ธก๋ฉด์— ์‹œ๊ฐ„์„ ์Ÿ๋Š” ๊ฒƒ๋ณด๋‹ค ๋‹ค๋ฅธ ์ฝ”๋“œ ๋ถ€๋ถ„์— ์ง‘์ค‘ํ•˜๋Š” ๊ฒƒ์ด ๋งž๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

 

์ด๋Ÿฌํ•œ ์ด์œ ๋กœ ๊ณผํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, TodoApp์— ์ ์šฉํ•ด๋ณด๊ธฐ๋กœ ํ•˜์˜€๋‹ค! 

# ์•„ํ† ๋ฏน ๋””์ž์ธ

์•„ํ† ๋ฏน ๋””์ž์ธ ์€ ํ™”ํ•™์  ๊ด€์ ์—์„œ ์˜๊ฐ์„ ์–ป์€ ๋””์ž์ธ ์‹œ์Šคํ…œ์œผ๋กœ  ์›์ž์—์„œ ๋ถ„์ž , ๋ถ„์ž์—์„œ ์œ ๊ธฐ์ฒด, ๊ถ๊ทน์ ์œผ๋กœ ๋ฌผ์งˆ๋กœ ๊ตฌ์„ฑ๋˜๋Š” ์ด๋Ÿฐ ํ™”ํ•™์  ๊ด€์ ์—์„œ ์˜๊ฐ์„ ์–ป์—ˆ๋‹ค๊ณ  ํ•œ๋‹ค.

์•„ํ† ๋ฏน ๋””์ž์ธ์€ ์ด ๋‹ค์„ฏ ๊ฐ€์ง€์˜ ๋‹จ๊ณ„๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. 

 

1. Atom : ๋” ์ด์ƒ ๋ถ„ํ•ดํ•  ์ˆ˜ ์—†๋Š” ๊ธฐ๋ณธ ์ปดํฌ๋„ŒํŠธ. (ex : button, input, text... )

2. Molecules :  ์—ฌ๋Ÿฌ ๊ฐœ์˜ atom์„ ๊ฒฐํ•ฉ. (ex  button ๊ณผ input ๊ฒฐํ•ฉํ•œ search ์ปดํฌ๋„ŒํŠธ )

label + input + button = molecules

3. Organisms : Molecules ๊ณผ Atom๋“ค์„ ์กฐํ•ฉํ•œ ์ปดํฌ๋„ŒํŠธ.

4. Templates : ์‹ค์ œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ ˆ์ด์•„์›ƒ์— ๋ฐฐ์น˜ํ•˜๊ณ  ๊ตฌ์กฐ๋ฅผ ์žก๋Š” ์™€์ด์–ด ํ”„๋ ˆ์ž„.

5. Pages : ์‹ค์ œ ํŽ˜์ด์ง€.

# Todo ์— ์ ์šฉํ•ด๋ณด์ž! 

## ๐Ÿค” ๊ณ ๋ฏผ  Todo ์— ๋ชจ๋“  ๋‹จ๊ณ„๋ฅผ ์ ์šฉํ•ด์•ผ ํ• ๊นŒ?  

์‚ฌ์‹ค Todo ์ž์ฒด๋„ Atom ๋””์ž์ธ์„ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋งŽ์ด ๊ณผํ•˜๊ธฐ์—.. ๋ชจ๋“  ๋‹จ๊ณ„๋ฅผ ์ ์šฉํ•  ํ•„์š”๊ฐ€ ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ๊ณ ๋ฏผ์ด ์ƒ๊ฒผ๋‹ค.

๊ทธ๋ž˜์„œ ๊ณ ๋ฏผ ๋์— organisms ๋‹จ๊ณ„๋ฅผ ์ œ์™ธํ•˜๊ณ  ์ ์šฉํ•ด๋ณด๊ธฐ๋กœ ํ•˜์˜€๋‹ค! 

##  โœ”๏ธ ์ ์šฉ

### Atoms

TodoApp ํŽ˜์ด์ง€๋Š” ์ด 6๊ฐœ๋‹ค. (๋žœ๋”ฉ / ํšŒ์›๊ฐ€์ž… / ๋กœ๊ทธ์ธ / Todos / ์ƒ์„ธ Todo / Todo ์ƒ์„ฑ )

ํŽ˜์ด์ง€์— ์‚ฌ์šฉ๋˜๋Š” ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๋ชจ๋‘ atoms ์œผ๋กœ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š๊ณ , ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋“ค๋งŒ Atoms ํด๋”์— ๊ตฌํ˜„ํ•˜์˜€๋‹ค.

๊ทธ๋ฆฌ๊ณ  styled-components ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐ›์•„์˜จ props.type ๋ณ„๋กœ style์„ ์ ์šฉํ•˜์—ฌ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์—ˆ๋‹ค! 

const ButtonWrapper = styled.button<{ btnType: string }>`
  width: ${(props) => (props.btnType === 'home' ? '50px' : '100px')};
  height: ${(props) => (props.btnType === 'home' ? '50px' : '40px')};
  background-color: ${(props) => {
    switch (props.btnType) {
      case 'add':
        return '#0a86f7';
      case 'logout':
        return 'white';
      case 'delete':
        return '#e7f5ff';
      default:
        return '#0a86f7';
    }
  }};
  color: ${(props) => {
    switch (props.btnType) {
      case 'logout':
        return '#228be6';
      case 'delete':
        return '#228be6';
      default:
        return 'white';
    }
  }};
  border: none;
  border-radius: ${(props) => (props.btnType === 'home' ? '50%' : '10px')};
  cursor: pointer;
`;
interface TitleProps {
  title: string;
  type: string;
}

const Title = ({ title, type }: TitleProps) => {
  return <TitleWrapper type={type}>{title}</TitleWrapper>;
};

export default Title;

const TitleWrapper = styled.h1<{ type: string }>`
  font-size: ${(props) => (props.type === 'card' ? '20px' : '30px')};
`;

### Molecules

Molecules ํด๋”๋Š” todo ํด๋”์™€ user ํด๋”๋กœ ๋‚˜๋ˆ„์–ด ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๊ตฌํ˜„ํ•˜์˜€๋‹ค.

Molecules๋กœ ๋‚˜๋ˆ„๋Š” ๊ธฐ์ค€์€ Atoms ๊ฐ€ ๋‘ ๊ฐœ ์ด์ƒ ํฌํ•จ๋˜๊ณ , ์ตœ์†Œํ•œ ํ•˜๋‚˜ ์ด์ƒ์˜ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€๋‹ค.

๋˜, ์žฌ์‚ฌ์šฉ์„ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๊ณ ๋ คํ•ด์„œ , ์žฌ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€๋Š”๋ฐ ์˜ˆ๋ฅผ ๋“ค์–ด ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์™€ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€์—์„œ input๊ณผ button์œผ๋กœ ๊ตฌ์„ฑ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ๋กœ ๊ตฌํ˜„ํ•˜์˜€๋Š”๋ฐ, page์—์„œ AccountForm์— url์„ props๋กœ ์ „๋‹ฌํ•ด์„œ url์— ๋”ฐ๋ผ ํšŒ์› ๊ฐ€์ž… or ๋กœ๊ทธ์ธ์œผ๋กœ ๊ตฌ๋ณ„ํ•ด์„œ post ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๋ฐฉ์‹์œผ๋กœ ํ•ด๋ณด์•˜๋‹ค. (-> ์ด ๋ฐฉ๋ฒ•์ด ๊ดœ์ฐฎ์€ ๊ฒƒ์ธ์ง€.. ์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹ค..)

ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ ํ…์ŠคํŠธ๋ฅผ ์ œ์™ธํ•˜๊ณ ๋Š” ๋˜‘๊ฐ™์€ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค!

  const onClick = async () => {
    if (url == 'create') {
      try {
        await instance.post(`/users/${url}`, {
          email: account.email,
          password: account.password,
        });
        navigate('/signin');
      } catch (err) {
        if (err instanceof Error) {
          SnackBar(err.message, 'error');
        }
      }
    } else {
      try {
        const res = await instance.post(`/users/${url}`, {
          email: account.email,
          password: account.password,
        });
        window.localStorage.setItem('token', res.data.token);
        setLoginState(true);
        navigate('/todolist');
      } catch (err) {
        if (err instanceof Error) {
          SnackBar(err.message, 'error');
        }
      }
    }
  };

pages / ๋กœ๊ทธ์ธ , ํšŒ์›๊ฐ€์ž…

### Template

๋ ˆ์ด์•„์›ƒ! Todo ์ƒ์„ฑ / ๋ฆฌ์ŠคํŠธ / ์ƒ์„ธ๋ณด๊ธฐ์—์„œ ์ ์šฉ๋˜๋Š” ๋ ˆ์ด์•„์›ƒ์ด ๋ชจ๋‘ ๋˜‘๊ฐ™๊ธฐ ๋•Œ๋ฌธ์— ํ•œ๋ฒˆ ๋งŒ๋“ค์–ด ๋ณด์•˜๋‹ค.

import React from 'react';
import styled from 'styled-components';

const Template = ({ children }: { children: React.ReactNode }) => {
  return <Container>{children}</Container>;
};

export default Template;

const Container = styled.div`
  display: grid;
  justify-items: center;
  padding-top: 60px;
`;

 

  return (
    <Template>
      <TodoHeader />
      <TodoCreateForm />
    </Template>
  );

### Pages 

 

# ์•„์‰ฌ์šด ์  = ๋ถ€์กฑํ•œ ์  = ์œ ์˜ํ•  ์  

1. ์ปดํฌ๋„ŒํŠธ ์žฌ์‚ฌ์šฉ์„ฑ์ด ๋†’์•„์กŒ์œผ๋‚˜, Props Drilling ์ด ์ž์นซํ•˜๋ฉด ๋งŽ์•„์งˆ ์ˆ˜ ์žˆ์–ด์„œ ์ฃผ์˜ํ•˜๋ฉด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๊ฒƒ ๊ฐ™๋‹ค. 

-> ์ด ๋ถ€๋ถ„์„ ์ฃผ์˜ํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋ฅผ atoms ๋กœ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š๊ณ , ๊ณตํ†ต์ ์œผ๋กœ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋“ค๋งŒ atoms ํด๋”์— ๋”ฐ๋กœ ๊ตฌํ˜„ํ•˜์˜€๋‹ค.  ๋‹ค๋งŒ ์ด๋Ÿฐ ๋ถ€๋ถ„๋„ ์ฃผ๊ด€์ ์ธ ๊ธฐ์ค€์—์„œ ๋ถ„๋ฆฌํ•œ ๊ฒƒ์ด๊ธฐ์—, ์ž˜ํ–ˆ๋‹ค๊ณ ๋Š” ํ™•์‹คํ•  ์ˆ˜ ์—†๋‹ค.

 

2. ๋‹จ๊ณ„๋ณ„ ๋ถ„๋ฆฌ ๊ธฐ์ค€.

-> Atoms ์„ ๊ตฌ๋ถ„ํ•˜๋Š” ๋ฐ ์žˆ์–ด์„œ๋Š” ์–ด๋ ต์ง€ ์•Š์•˜์ง€๋งŒ, molecules์„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ธฐ์ค€์„ ์ •ํ•˜๋Š” ๊ฒƒ์— ์žˆ์–ด์„œ ์–ด๋ ค์›€์ด ์žˆ์—ˆ๋‹ค.

 ์ผ๋‹จ Atoms ์ปดํฌ๋„ŒํŠธ๊ฐ€ 2๊ฐœ ์ด์ƒ ๋“ค์–ด์žˆ๊ณ , ๋‚˜๋ฆ„์˜ ๊ธฐ์ค€์œผ๋กœ ํ•˜๋‚˜์˜ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰! ์„ ๊ธฐ์ค€์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ธด ํ–ˆ๋Š”๋ฐ, TodoApp ์€ ๊ตฌ์„ฑ ์ž์ฒด๊ฐ€ ๊ฐ„๋‹จํ•˜๊ณ  Organisms ๋‹จ๊ณ„๋ฅผ ์ œ์™ธํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋‚˜๋งˆ ๊ดœ์ฐฎ์•˜๋‹ค. ๋งŒ์•ฝ ํŒ€ํ”„๋กœ์ ํŠธ ๊ฐ™์€ ๋ณต์žกํ•œ ๊ตฌ์กฐ์—์„œ Organisms ๋‹จ๊ณ„๋ฅผ ํฌํ•จ์‹œ์ผฐ๋‹ค๋ฉด, Molecules์™€ Organisms๋ฅผ ๋ถ„๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ์ค€์„ ์ •ํ•˜๊ธฐ ์œ„ํ•ด ์—„์ฒญ๋‚œ... ๊ณ ๋ฏผ์„ ํ–ˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.

 

๋งˆ์ง€๋ง‰์œผ๋กœ ํŒ€ ํ”„๋กœ์ ํŠธ์—์„œ ์•„ํ† ๋ฏน ๊ตฌ์กฐ๋ฅผ ์ ์šฉํ•˜์ง€ ๋ชปํ•ด์„œ ๊ถ๊ธˆ์ฆ๋งŒ ์ปค์ ธ๊ฐ”๋Š”๋ฐ, ์ž‘์€ Todo ํ”„๋กœ์ ํŠธ์ง€๋งŒ ์ด๋ ‡๊ฒŒ ์ ์šฉํ•ด๋ณด๊ณ  ์•„ํ† ๋ฏน ๊ตฌ์กฐ์˜ ์žฅ๋‹จ์ ์„ ์ฒด๊ฐํ•˜๊ณ  ๊ถ๊ธˆ์ฆ์ด ํ•ด์†Œ๋˜์—ˆ๋‹ค! ๐Ÿ˜Š ๋งŒ์•ฝ ๋‹ค์Œ์— ์•„ํ† ๋ฏน ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•  ์ผ์ด ์ƒ๊ธด๋‹ค๋ฉด, ์ง€๊ธˆ ๋А๋‚€ ์žฅ๋‹จ์ ์„ ๊ธฐ์–ตํ•˜๋ฉด์„œ!  ์ตœ๋Œ€ํ•œ ๋‹จ์ ์„ ์ค„์ผ ์ˆ˜ ์žˆ๋„๋ก ๋…ธ๋ ฅํ•˜์ž !