🧩 ν•©μ„± μ»΄ν¬λ„ŒνŠΈλ‘œ 효율적으둜 κ°œλ°œν•˜κΈ°

sujinΒ·2024λ…„ 9μ›” 19일
1
post-thumbnail

ν”„λ‘ νŠΈμ—”λ“œ κ°œλ°œμ—μ„œ 빠질 수 μ—†λŠ” 뢀뢄이 μ»΄ν¬λ„ŒνŠΈ 개발인 것 κ°™μŠ΅λ‹ˆλ‹€. κ²‰μœΌλ‘œ λ³΄κΈ°μ—λŠ” λ‹¨μˆœν•΄ 보일 수 μžˆμ§€λ§Œ μžμ„Ένžˆ 듀여닀보면 μ–΄λ–€ κ°œλ°œλ³΄λ‹€λ„ μ„¬μ„Έν•˜κ³  λ³΅μž‘ν•œ μž‘μ—…μ΄λΌλŠ” 생각이 λ“­λ‹ˆλ‹€. ν˜„μž¬ μ €λŠ” κ°œλ°œν•  λ•Œ μ»΄ν¬λ„ŒνŠΈλ₯Ό 두가지 κΈ°μ€€μœΌλ‘œ λ‚˜λˆ μ„œ μž‘μ—…ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. λ‹¨μˆœ UI λ₯Ό ν‘œν˜„ν•˜λŠ” common μ»΄ν¬λ„ŒνŠΈμ™€ UI+κΈ°λŠ₯ 을 λ‹€λ£¨λŠ” feature μ»΄ν¬λ„ŒνŠΈ μž…λ‹ˆλ‹€. ( μ—¬κΈ°μ„œ κΈ°λŠ₯의 기쀀은 μ»΄ν¬λ„ŒνŠΈμ•ˆμ—μ„œ APIλ₯Ό ν˜ΈμΆœν•˜μ—¬ 데이터λ₯Ό λ‹€λ£¨κ±°λ‚˜, μƒνƒœκ΄€λ¦¬λ₯Ό ν•¨μœΌλ‘œμ¨ UI의 λ³€ν™”λ₯Ό μ£ΌλŠ” 것을 λ§ν•©λ‹ˆλ‹€. )

μ œκ°€ μ†Œκ°œν•  ν•©μ„± μ»΄ν¬λ„ŒνŠΈλŠ” feature μ»΄ν¬λ„ŒνŠΈμ— μ†ν•΄μžˆλŠ” μ»΄ν¬λ„ŒνŠΈ 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€. 이번 ν¬μŠ€νŒ…μ—μ„œλŠ” ν•©μ„± μ»΄ν¬λ„ŒνŠΈλž€ 무엇이고, ν•©μ„± μ»΄ν¬λ„ŒνŠΈλ₯Ό μ μš©ν•œ 과정에 λŒ€ν•΄μ„œ μ†Œκ°œν•΄λ³΄λ €κ³  ν•©λ‹ˆλ‹€.



ASIS μ»΄ν¬λ„ŒνŠΈ

였늘 λ‹€λ£° μ»΄ν¬λ„ŒνŠΈλŠ” μ±… UIλ₯Ό λ‚˜νƒ€λ‚΄λŠ” μ»΄ν¬λ„ŒνŠΈμž…λ‹ˆλ‹€. (νŽΈμ˜μƒ Bookμ»΄ν¬λ„ŒνŠΈλΌκ³  λΆ€λ₯΄κ² μŠ΅λ‹ˆλ‹€!) APIλ₯Ό ν˜ΈμΆœν•΄μ„œ 책에 λŒ€ν•œ 정보(μ±… 이미지, μ±… 이름, μΆœνŒμ‚¬ 이름, μ±… ν”Œλž˜κ·Έ)λ₯Ό λ°›μ•„μ˜€κ³  이λ₯Ό UI에 맞게 λ°°μΉ˜ν•΄μ„œ λ³΄μ—¬μ€λ‹ˆλ‹€.

μœ„μ™€ 같은 Book μ»΄ν¬λ„ŒνŠΈλ₯Ό κ΅¬ν˜„ν•˜κΈ° μœ„ν•œ μ½”λ“œλŠ” μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€. (이해λ₯Ό 돕기 μœ„ν•œ μ˜ˆμ‹œλ‘œ μƒλž΅λœ 뢀뢄이 μžˆμœΌλ‹ˆ μ°Έκ³ ν•΄μ„œ λ΄μ£Όμ„Έμš”!)


import Text from "components/common/text"
import Flag from "components/common/flag"
import OriginalBook from "components/features/original/book"
import OriginalBookImage from "components/features/original/book/image"
import OriginalBook from "components/features/original/book/caption"
import MySchoolBookImage from "components/features/original/book/svg/image"


const BookList = () => {
  	...
  
	return (
      ...
      
                {gerOriginalSchoolBookListResponse.data.book_list.map((item, index) => {
              return (
                <OriginalBook
                  key={item.id}
                  onClick={() => onClickBookItem(item.id)}
                >
                  {/* μ±… 이미지 png 파일 */}
                  {item.thumbnail_url && <OriginalBookImage src={item.thumbnail_url} />}
                    {/* μ±… 이미지 svg 파일 */}
                  {item.my_school_thumbnail_detail && (
                    <MySchoolBookImage schoolName={schoolName} subsubjectName={item.subsubject_name} colorDetail={item.my_school_thumbnail_detail} />
                  )}
                  {/* μ±… μΆœνŒμ‚¬ */}
                  {item.school_publisher_name && (
                    <Text type="caption2" color="gray_400">
                      {item.school_publisher_name}
                    </Text>
                  )}
                  {/* μ±… 이름 */}
                  <OriginalBookCaption>{item.name}</OriginalBookCaption>
                  {!AuthOriginalActive?.is_active && item.is_trial && <Flag type="book">이 λ‹¬μ˜ 무료 λ¬Έμ œμ§‘</Flag>}
                   {/* μ±… ν”Œλž˜κ·Έ */}
                  {!isOpen(item.opened_at) && (
                    <Flag type="book" color="blue_400">
                      {getMonth(item.opened_at)} 말 OPEN μ˜ˆμ •
                    </Flag>
                  )}
                </OriginalBook>
              )
            })}
            
     ...
    
    )
}

이해λ₯Ό 돕기 μœ„ν•΄ μœ„ μ½”λ“œμ— λŒ€ν•΄μ„œ κ°„λ‹¨νžˆ μ„€λͺ…ν•˜μžλ©΄

  • gerOriginalSchoolBookListResponse λŠ” 책에 λŒ€ν•œ 정보λ₯Ό κ°–κ³  μžˆλŠ” API response κ°’ μž…λ‹ˆλ‹€.
  • <OriginalBook /> 은 <OriginalImage /> , <OriginalCaption /> λ“± 책을 κ΅¬μ„±ν•˜λŠ”λ° ν•„μš”ν•œ μš”μ†Œλ“€μ„ μžμ‹μœΌλ‘œ λ°›λŠ” λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈμž…λ‹ˆλ‹€.
  • <OriginalImage /> 은 μ±…μ˜ png 이미지λ₯Ό λ‚˜νƒ€λ‚΄λŠ” μ»΄ν¬λ„ŒνŠΈ μž…λ‹ˆλ‹€.
  • <OriginalCaption /> 은 μ±…μ˜ 이름을 λ‚˜νƒ€λ‚΄λŠ” μ»΄ν¬λ„ŒνŠΈ μž…λ‹ˆλ‹€.
  • <MySchoolBookImage /> 은 μ±…μ˜ svg 이미지λ₯Ό λžœλ”λ§ ν•΄μ£ΌλŠ” μ»΄ν¬λ„ŒνŠΈ μž…λ‹ˆλ‹€.
  • <Flag /> λŠ” μ±…μ˜ ν”Œλž˜κ·Έ(9μ›” 말 μ˜€ν”ˆμ˜ˆμ • λ“±)λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 곡용 μ»΄ν¬λ„ŒνŠΈ μž…λ‹ˆλ‹€.
  • <Text /> λŠ” μΆœνŒμ‚¬ 이름을 λ‚˜νƒ€λ‚΄λŠ” 곡용 μ»΄ν¬λ„ŒνŠΈ μž…λ‹ˆλ‹€.

문제점

μœ„μ™€ 같은 λ°©μ‹μœΌλ‘œ μ»΄ν¬λ„ŒνŠΈλ₯Ό κ΅¬μ„±ν–ˆμ„ λ•Œ μ œκ°€ 느꼈던 λ¬Έμ œμ μ€ μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

  1. 맀번 <OriginalBook>, <OriginalBookImage>, <OriginalBookCaption> 을 각각 import ν•΄μ•Όν•©λ‹ˆλ‹€.
  2. <OriginalBookCaption> 을 μ‚¬μš© 기쀀이 κ°œλ°œμžλ§ˆλ‹€ λ‹€λ¦…λ‹ˆλ‹€.
    • <OriginalBookCaption> props둜 이름을 λ°›λŠ”κ²Œ μ•„λ‹ˆλΌ children으둜 λ°›κ³  μžˆμ–΄μ„œ λˆ„κ΅¬λŠ” μ±… 이름, μ±… μΆœνŒμ‚¬κΉŒμ§€ ν¬ν•¨ν•˜κ³ , λˆ„κ΅¬λŠ” μ±… μ΄λ¦„κΉŒμ§€λ§Œ ν¬ν•¨μ‹œν‚€κ³  μ±… μΆœνŒμ‚¬λŠ” λ”°λ‘œ μΆ”κ°€ν•˜λŠ” λ°©μ‹μœΌλ‘œ μ‚¬μš©λ˜μ–΄ ν˜‘μ—…μ‹œ ν˜Όλž€μ„ μ£Όκ³  μžˆμŠ΅λ‹ˆλ‹€.
  3. <OriginalBookImage> 은 ν˜„μž¬ png 파일만 λ°›κ³  μžˆμ–΄μ„œ svg 파일의 경우 각각 νŽ˜μ΄μ§€λ§ˆλ‹€ ν•΄λ‹Ή μ»΄ν¬λ„ŒνŠΈ <MySchoolBookImage> λ₯Ό import ν•΄μ„œ μΆ”κ°€ν•΄μ•Ό ν•©λ‹ˆλ‹€.
  4. μ±… ν”Œλž˜κ·Έ(이 λ‹¬μ˜ 무료 λ¬Έμ œμ§‘, μ˜€ν”ˆμ˜ˆμ •, λ‚΄μ‹ μ—°κ΅¬μ†Œ 단독)λ₯Ό ν‘œμ‹œν•΄μ£Όλ €λ©΄ 맀번 <Flag> μ»΄ν¬λ„ŒνŠΈλ₯Ό import ν•΄μ„œ μΆ”κ°€ν•΄μ•Ό ν•©λ‹ˆλ‹€.
  5. λͺ¨λ“  response 값에 λŒ€ν•΄μ„œ κ·Έ 값이 μ‘΄μž¬ν•˜λŠ”μ§€ μ•„λ‹Œμ§€μ— λŒ€ν•΄μ„œ 체크λ₯Ό ν•˜λŠ” 둜직이 맀번 ν•„μš”ν•©λ‹ˆλ‹€.

κ°œμ„ μ 

  1. Book μ»΄ν¬λ„ŒνŠΈλ₯Ό κ΅¬μ„±ν•˜κΈ° μœ„ν•œ μš”μ†Œλ“€μ„ 각각 import ν•˜μ§€ μ•Šκ³  ν•œλ²ˆλ§Œ importν•΄μ„œ μ‚¬μš© ν•  수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.
  2. 각 μ»΄ν¬λ„ŒνŠΈμ˜ 기쀀을 μ •ν™•ν•˜κ²Œ μ •μ˜ν•˜μ—¬ κ°œλ°œμžκ°€ μ‚¬μš©ν•˜λŠ”λ° μžˆμ–΄ ν˜Όλž€μ„ μ€„μž…λ‹ˆλ‹€.
  3. μ»΄ν¬λ„ŒνŠΈμ˜ μ‚¬μš© μ—¬λΆ€(보여지고 μ•ˆλ³΄μ—¬μ§€κ³ )에 λŒ€ν•œ λ‘œμ§μ€ μ»΄ν¬λ„ŒνŠΈλ₯Ό importν•˜λŠ” νŽ˜μ΄μ§€μ—μ„œ μ²˜λ¦¬ν•˜λŠ” 것이 μ•„λ‹Œ ν•΄λ‹Ή μ»΄ν¬λ„ŒνŠΈμ—μ„œ μ²˜λ¦¬ν•˜λ„λ‘ ν•©λ‹ˆλ‹€.


TOBE μ»΄ν¬λ„ŒνŠΈ

μœ„μ— κ°œμ„ μ μ„ λ°˜μ˜μ‹œν‚€κΈ° μœ„ν•œ 방법을 찾아보닀가 ν•©μ„± μ»΄ν¬λ„ŒνŠΈμ— λŒ€ν•΄μ„œ μ•Œκ²Œ λ˜μ—ˆκ³  μ œκ°€ ν•˜λ €κ³  ν•˜λŠ” λ°©ν–₯μ„±κ³Ό λ§žλ‹€κ³  νŒλ‹¨λ˜μ–΄ μ μš©ν•˜κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€. λ¨Όμ € ν•©μ„± μ»΄ν¬λ„ŒνŠΈμ— λŒ€ν•΄μ„œ κ°„λ‹¨νžˆ μ†Œκ°œν•˜λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.

ν•©μ„± μ»΄ν¬λ„ŒνŠΈλž€?

ν•©μ„± μ»΄ν¬λ„ŒνŠΈλŠ” ν•˜λ‚˜μ˜ μ»΄ν¬λ„ŒνŠΈλ₯Ό μ—¬λŸ¬ 가지 μ§‘ν•©μ²΄λ‘œ λΆ„λ¦¬ν•œ λ’€, λΆ„λ¦¬λœ 각 μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‚¬μš©ν•˜λŠ” μͺ½μ—μ„œ μ‘°ν•©ν•΄μ„œ μ‚¬μš©ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈ νŒ¨ν„΄μ„ μ˜λ―Έν•©λ‹ˆλ‹€.

κ°„λ‹¨ν•œ μ˜ˆμ‹œλ‘œ html의 selectλ₯Ό λ³Ό 수 μžˆλŠ”λ°, selectλŠ” <select>와 <option> νƒœκ·Έμ˜ μ‘°ν•©μœΌλ‘œ μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€. <select>와 <option>은 각각 λ…λ¦½μ μœΌλ‘œλŠ” 큰 μ˜λ―Έκ°€ μ—†μ§€λ§Œ μ‚¬μš©ν•˜λŠ” κ³³μ—μ„œ 이λ₯Ό μ‘°ν•©ν•΄ μ‚¬μš©ν•¨μœΌλ‘œμ¨ 화면에 의미 μžˆλŠ” μš”μ†Œκ°€ λ©λ‹ˆλ‹€.


<select>
  <option value="1">Option 1</option>
  <option value="2">Option 2</option>
</select>

κ΅¬ν˜„ν•˜κΈ°

ν•©μ„± μ»΄ν¬λ„ŒνŠΈ νŒ¨ν„΄μ„ μ μš©ν•œ μ˜ˆμ‹œλ₯Ό μœ„ν•΄ 각각의 μ»΄ν¬λ„ŒνŠΈλ“€μ˜ μƒμ„Έν•œ props 와 λ‘œμ§λ“€μ€ ν¬ν•¨λ˜μ–΄ μžˆμ§€ μ•ŠμœΌλ‹ˆ 이 점 μ°Έκ³ ν•΄μ„œ λ΄μ£Όμ„Έμš”!

1. μ„œλΈŒ μ»΄ν¬λ„ŒνŠΈ

html의 <option> νƒœκ·Έμ— ν•΄λ‹Ήν•˜λŠ” μ„œλΈŒ μ»΄ν¬λ„ŒνŠΈλ₯Ό κ΅¬ν˜„ν•©λ‹ˆλ‹€. Book μ»΄ν¬λ„ŒνŠΈλ₯Ό κ΅¬μ„±ν•˜λŠ” 각각의 μ»΄ν¬λ„ŒνŠΈλ“€μ΄ 여기에 ν•΄λ‹Ήν•©λ‹ˆλ‹€. <BookImage> <BookCaption> <BookFlag>

2. 메인 μ»΄ν¬λ„ŒνŠΈ

html의 <select> νƒœκ·Έμ— ν•΄λ‹Ήν•˜λŠ” 메인 μ»΄ν¬λ„ŒνŠΈλ₯Ό κ΅¬ν˜„ν•©λ‹ˆλ‹€. μ„œλΈŒ μ»΄ν¬λ„ŒνŠΈλ“€μ„ λ¬Άμ–΄μ„œ 화면에 μ μž˜ν•˜κ²Œ 보이도둝 ν•˜λŠ” Wrapper μ„±κ²©μ˜ μ»΄ν¬λ„ŒνŠΈμž…λ‹ˆλ‹€.

import styled from "@emotion/styled"
import {ClickMotion} from "@repo/ui"

export interface OriginalBookGroupProps extends OriginalBookContextValue {
  children: React.ReactNode
  onClick?: () => void
}

export type Props = OriginalBookGroupProps & HTMLAttributes<HTMLDivElement>

export const OriginalBookGroup: React.FC<Props> = ({children, onClick, ...props}) => {

  return (
      <ClickMotion onClick={onClick}>
        <Wrapper {...props}>
          {children}
        </Wrapper>
      </ClickMotion>
  )
}

const Wrapper = styled.div<{width?: string}>`
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
`

μœ„μ²˜λŸΌ μž‘μ„±ν•˜λ©΄ children으둜 λ“€μ–΄μ˜€λŠ” μ„œλΈŒ μ»΄ν¬λ„ŒνŠΈλ“€μ„ 받을 수 있고 μˆœμ„œλŒ€λ‘œ 배치 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

3. 메인 & μ„œλΈŒλ₯Ό λ¬Άμ–΄μ„œ exportν•˜κΈ°

μ΄λ ‡κ²Œ κ΅¬ν˜„λœ μ»΄ν¬λ„ŒνŠΈλ“€μ„ λ¬Άμ–΄μ„œ exportν•˜λ©΄ 각각의 μ»΄ν¬λ„ŒνŠΈκ°€ Book의 μ„œλΈŒ μ»΄ν¬λ„ŒνŠΈμž„μ„ μ’€ 더 ν™•μ‹€ν•˜κ²Œ ν•  수 μžˆμ–΄ μ½”λ“œμ˜ 가독성에 도움이 될 수 μžˆμŠ΅λ‹ˆλ‹€.

import {OriginalBookGroup} from "./group"
import {OriginalBookImage} from "./image"
import {OriginalBookCaption} from "./caption"
import {OriginalBookFlag} from "./flag"

export const OriginalBook = Object.assign(OriginalBookGroup, {
  Image: OriginalBookImage,
  Caption: OriginalBookCaption,
  Flag: OriginalBookFlag
})

4. κ²°κ³Ό

import { OriginalBook } from "components/features/original/book"


const BookList = () => {
  	...
  
	return (
      ...
            {gerOriginalSchoolBookListResponse.data.book_list.map((item, index) => (
              <OriginalBook key={item.id} onClick={() => onClickBookItem(item.id)}>
                <OriginalBook.Flag isTrial={item.is_trial} isLms={item.is_lms_exclusive} openedAt={item.opened_at} />
                <OriginalBook.Image
                  pngUrl={item.thumbnail_url}
                  svgColorInfo={item.my_school_thumbnail_detail}
                  subsubjectName={item.subsubject_name}
                />
                <OriginalBook.Caption bookName={item.name} publisherName={item.school_publisher_name} />
              </OriginalBook>
            ))}
            
     ...
    
    )
}

λ¬Έμ„œν™”ν•˜κΈ°

μœ„μ— κ°œμ„ μ  쀑에 ν•˜λ‚˜μΈ κ°œλ°œμžλ“€μ΄ μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‚¬μš©ν•  λ•Œ ν˜Όλ™μ„ 쀄이기 μœ„ν•΄μ„œλŠ” μ»΄ν¬λ„ŒνŠΈμ— λŒ€ν•œ λ¬Έμ„œμžλ£Œκ°€ ν•„μš”ν–ˆμŠ΅λ‹ˆλ‹€. μ»΄ν¬λ„ŒνŠΈλ₯Ό λ¬Έμ„œν™”ν•˜λŠ” λ„κ΅¬μ—λŠ” μŠ€ν† λ¦¬λΆκ³Ό 같은 λΌμ΄λΈŒλŸ¬λ¦¬λ“€μ΄ μ‘΄μž¬ν•˜μ§€λ§Œ λ°”λ‘œ λ„μž…ν•˜κΈ°μ—λŠ” λŸ¬λ‹μ»€λΈŒκ°€ μžˆλ‹€λŠ” 것을 κ³ λ €ν•˜μ—¬ 일단 ν”Όκ·Έλ§ˆμ— μ •λ¦¬ν•΄μ„œ νŒ€μ›λ“€μ—κ²Œ κ³΅μœ ν–ˆμŠ΅λ‹ˆλ‹€.



마무리

μ»΄ν¬λ„ŒνŠΈ κ°œμ„  ν›„ 이전보닀 간단해진 μ½”λ“œλ₯Ό λ³΄λ©΄μ„œ λΏŒλ“―ν•¨μ„ λŠκΌˆλ‹€. 이 점이 λ¦¬νŒ©ν† λ§ν•˜λŠ” 큰 이유 쀑 ν•˜λ‚˜μΈ 것 κ°™λ‹€. 처음 ν•©μ„± μ»΄ν¬λ„ŒνŠΈ κ°œλ…μ— λŒ€ν•΄μ„œ μ ‘ν–ˆμ„ λ•ŒλŠ” 잘 이해가 가지 μ•Šμ•˜λŠ”λ° λ‚΄κ°€ μ‹€μ œλ‘œ μ»΄ν¬λ„ŒνŠΈμ— μ μš©ν•  λͺ©μ μœΌλ‘œ 계속 보닀 λ³΄λ‹ˆ μ΄ν•΄ν•˜κΈ°κ°€ μˆ˜μ›”ν–ˆλ˜ 것 κ°™λ‹€. μ—­μ‹œ λ‚˜λŠ” μ‹€μ œλ‘œ λ‚΄κ°€ λΆ€λ”ͺν˜€λ΄μ•Ό μ•„λŠ” 것 κ°™λ‹€!γ…Žγ…Ž

μ»΄ν¬λ„ŒνŠΈ κ°œλ°œμ€ 항상 처음 μ‹œμž‘ν•  λ•ŒλŠ” 이 μ •λ„λŠ” 금방 ν•˜κ² μ§€? λΌλŠ” 마음으둜 μ‹œμž‘ν•˜λŠ”λ° ν•˜λ‹€ 보면 μ–΄λ €μš΄ 점이 μƒκ²¨μ„œ 길게 κ³ λ―Όν•˜κ²Œ λ˜λŠ” 것 κ°™λ‹€. 근데 λ‚˜λŠ” 이런 κ³ λ―Όν•˜λŠ” μ‹œκ°„μ΄ λ‚˜μ˜μ§€λ§Œμ€ μ•Šμ€ 것 κ°™λ‹€. 이런 고민을 ν†΅ν•΄μ„œ μ»΄ν¬λ„ŒνŠΈκ°€ λ‹¨μˆœνžˆ κΈ°λŠ₯μ΄λ‚˜ UI λ‹¨μœ„λ‘œ μͺΌκ°œλ†“κΈ°λ§Œ ν•œ 것이 μ•„λ‹ˆλΌ μ§„μ§œ 효율적인 κ°œλ°œμ„ μœ„ν•œ μˆ˜μ€€ 높은 μ»΄ν¬λ„ŒνŠΈκ°€ 될 수 μžˆλŠ” κ³Όμ •μ΄λΌλŠ” 생각이 λ“€κΈ° λ•Œλ¬Έμ΄λ‹€. 그리고 λ‚΄κ°€ κ°œλ°œν•œ μ»΄ν¬λ„ŒνŠΈλ₯Ό λ‹€λ₯Έ κ°œλ°œμžλ“€μ΄ νŽΈν•˜κ²Œ μ“°κ³  μΌκ΄€λœ μ½”λ“œμ™€ UIλ₯Ό 보면 κ·Έλ•Œλ§ŒνΌ 또 λΏŒλ“―ν•œ κ²Œμ—†λŠ” 것같닀!γ…‹γ…‹γ…‹

이번 μ»΄ν¬λ„ŒνŠΈ κ°œμ„ μ„ ν•˜λ©΄μ„œ μ•„μ‰¬μ› λ˜ 점은 λ¬Έμ„œν™” 뢀뢄이닀. μ˜ˆμ „μ— μŠ€ν† λ¦¬λΆμ„ λ„μž…ν•˜λ €κ³  ν–ˆμ—ˆλŠ”λ° κ·Έ λ‹Ήμ‹œ λ‹€λ₯Έ κΈ°λŠ₯ κ°œλ°œμ— μš°μ„ μˆœμœ„κ°€ λ°€λ €μ„œ μ œλŒ€λ‘œ λ„μž…ν•˜μ§€ λͺ»ν–ˆμ—ˆλ‹€. 이제 μ»΄ν¬λ„ŒνŠΈκ°€ 점점 λ§Žμ•„μ§€λ©΄μ„œ λ¬Έμ„œν™”μ˜ ν•„μš”μ„±μ— λŒ€ν•΄μ„œ 크게 느끼고 μžˆλ‹€. ν•˜λ£¨λΉ¨λ¦¬ μŠ€ν† λ¦¬λΆμ„ μ œλŒ€λ‘œ λ„μž…ν•΄μ„œ μ œλŒ€λ‘œ 된 λ””μžμΈμ‹œμŠ€ν…œμ„ κ΅¬μΆ•ν•˜κ³  μ‹Άλ‹€!



πŸ“š μ°Έκ³ 

ν•©μ„± μ»΄ν¬λ„ŒνŠΈλ‘œ μž¬μ‚¬μš©μ„± κ·ΉλŒ€ν™”ν•˜κΈ°

profile
κ°œλ°œλŒ•λ°œ

0개의 λŒ“κΈ€