Loading
Loading
블로그 개발 일지 #3 - 공통 컴포넌트
2024년 11월 12일
전 팀 프로젝트에서 만들었던 토스트 팝업을 가져와서 사용하기로 했습니다. react-hot-toast
를 참고해서 만들었습니다.
토스트는 Toast.ts, Toaster.tsx, ToastStore.ts로 이루어져 있으며, Zustand를 활용하여 전역으로 상태를 관리하였습니다.
ToastStore
을 이용해서 토스트를 추가, 수정, 삭제하는 함수를 제공합니다.
id
를 통해 특정 토스트를 식별하고, 메시지와 타입, 지속 시간을 변경합니다.id
를 이용해 특정 토스트를 선택적으로 삭제합니다.promise
가 실행 중일 때 loading
메시지를 먼저 띄우고, 작업이 완료되면 success
메시지를, 실패하면 error
메시지를 표시합니다.useToastStore
라는 상태 저장소를 만들어 여러 종류의 토스트 메시지를 추가, 수정, 삭제할 수 있도록 합니다.react-hook-form
을 사용하여 Form 컴포넌트를 만들었습니다.
Form은 컴파운트 컴포넌트 패턴을 사용해서 만들었습니다.
이 코드에서는 Form
, Input
, Textarea
, Error
, Submit
컴포넌트들이 있으며, 이들을 하나의 컴포넌트로 결합하여 폼을 구성합니다.
각 컴포넌트의 역할을 간단히 설명하겠습니다.
FormProvider
를 통해 React Hook Form의 상태를 하위 컴포넌트에서 사용할 수 있도록 전파합니다.onSubmit
핸들러로 폼 제출 시 실행될 함수를 받으며, handleSubmit
을 통해 폼 데이터를 관리합니다.name
을 인수로 받아 해당 필드의 에러 상태를 검사합니다.type
이 "password"
인 경우, 아이콘을 클릭하여 비밀번호를 표시하거나 숨길 수 있습니다.register
함수를 사용해 React Hook Form에 등록됩니다. 이를 통해 입력 값을 관리하고 유효성 검사를 수행합니다.register
함수를 사용해 입력 값을 관리합니다.text
프로퍼티로 받아서 기본값은 "입력"으로 설정됩니다.Form.Error
, Form.Input
, Form.Textarea
, Form.Submit
형태로 쉽게 접근할 수 있습니다.서버 상태를 관리하기 위해서 리액트 쿼리를 사용했습니다.
공식 홈페이지를 참고하여 QueryProvider를 설정하였습니다.
리액트 쿼리를 이용하여 서버에게서 받은 데이터를 캐싱하여 관리하여 반복적인 요청을 줄이고 클라이언트의 요청에 따라서 최신 상태를 유지합니다.
svg 이미지를 .tsx 파일로 변환하여 src/icons/
폴더에서 관리를 합니다.
// src/types/IconType.ts interface IconType { width?: number | string; height?: number | string; color?: string; } // src/icons/Favorite.tsx export function FavoriteEmpty({ width = 24, height = 24, color = "#fff" }: IconType) { return ( <svg xmlns="http://www.w3.org/2000/svg" height={height} viewBox="0 -960 960 960" width={width} fill={color}> <path d="m480-120-58-52q-101-91-167-157T150-447.5Q111-500 95.5-544T80-634q0-94 63-157t157-63q52 0 99 22t81 62q34-40 81-62t99-22q94 0 157 63t63 157q0 46-15.5 90T810-447.5Q771-395 705-329T538-172l-58 52Zm0-108q96-86 158-147.5t98-107q36-45.5 50-81t14-70.5q0-60-40-100t-100-40q-47 0-87 26.5T518-680h-76q-15-41-55-67.5T300-774q-60 0-100 40t-40 100q0 35 14 70.5t50 81q36 45.5 98 107T480-228Zm0-273Z" /> </svg> ); } // used <FavoriteEmpty width={18} height={18} color="var(--text-primary)" />
이렇게 SVG를 .tsx 파일로 관리하는 이유는 다음과 같습니다