블로그

codestudy

[인프런 워밍업 스터디 클럽 3기 풀스택] 2주차 발자국

🚀 Dropbox 클론코딩 - 파일 스토리지 서비스 제작하기📚 강의 수강일주일 동안 학습한 내용 요약🔧 프로젝트 설정 (섹션 4-2)Next.js 프로젝트 초기 설정 방법Tailwind CSS와 TypeScript 환경 구성Material-Tailwind, React Query 등 필요한 라이브러리 설치프로젝트 페이지 구조와 레이아웃 설정환경 변수(.env) 구성🎨 UI 구축 (섹션 4-3)Dropbox 클론의 직관적인 인터페이스 구현logo.tsx, dropbox-image, search-component 등 재사용 컴포넌트 개발Next.js의 이미지 처리와 정적 파일 관리Tailwind CSS의 flex, grid 시스템을 활용한 반응형 디자인useState 훅을 활용한 검색 기능 상태 관리🗄 Supabase Storage 설정 및 파일 업로드 (섹션 4-4)Supabase Storage 버킷 생성 및 설정Form 요소와 onSubmit 이벤트를 활용한 파일 업로드 기능FormData 객체를 활용한 파일 데이터 처리React Query의 useMutation 훅을 통한 파일 업로드 상태 관리업로드된 이미지 URL 생성 및 표시🔄 고급 기능 구현 (섹션 4-5)Supabase Storage의 remove 함수를 활용한 파일 삭제 기능react-dropzone 라이브러리를 활용한 드래그 앤 드롭 구현useDropZone 훅 활용 및 onDrop 콜백 함수 설정multiple 옵션을 활용한 여러 파일 동시 업로드 기능Promise.all을 활용한 비동기 파일 업로드 병렬 처리로딩 상태 표시 및 사용자 피드백 개선학습 내용 회고이번 주 학습을 통해 Next.js와 TypeScript를 활용한 모던 웹 애플리케이션 개발 과정을 경험할 수 있었습니다. TypeScript의 타입 시스템을 적극 활용하면서 인터페이스 정의와 컴포넌트 타입 적용에 많은 배움이 있었지만, Material Tailwind 컴포넌트와의 타입 호환성 문제를 해결하는 과정에서 any 타입을 사용한 것은 아쉬움으로 남습니다.  🛠 미션 해결 과정TypeScript 타입 문제 해결Material Tailwind 컴포넌트와 TypeScript의 타입 호환성 문제에 직면했을 때, 다음과 같은 과정으로 해결했습니다:문제 정의: IconButton, Input, Spinner 등의 컴포넌트에서 다음과 같은 TypeScript 타입 에러가 발생했습니다.'{ value: string; onChange: (e: ChangeEvent<HTMLInputElement>) => void; label: string; icon: Element; }' 형식에 'Pick<InputProps, ... 284 more ... | "shrink">' 형식의 onPointerEnterCapture, onPointerLeaveCapture 속성이 없습니다. 해결 방안 탐색: 여러 가지 해결 방법을 고려했습니다:@ts-ignore 또는 @ts-expect-error 주석 사용타입 단언(Type Assertion) 사용props 객체와 any 타입 활용효율적인 접근법 선택: 코드 가독성과 유지보수성을 고려하여 props 객체와 any 타입을 활용하는 방법을 선택했습니다:const inputProps: any = { value: searchInput, onChange: (e: ChangeEvent<HTMLInputElement>) => setSearchInput(e.target.value), label: "Search Images", icon: <i className="fa-solid fa-magnifying-glass" /> }; return <MaterialInput {...inputProps} />; 일관된 패턴 적용: 비슷한 문제가 발생하는 다른 컴포넌트에도 동일한 패턴을 적용하여 코드의 일관성을 유지했습니다. 예를 들어 IconButton, Spinner 등의 컴포넌트에도 같은 방식으로 타입 문제를 해결했습니다.로딩 상태 처리: boolean 값 처리 문제도 해결했습니다.// 경고: Received `false` for a non-boolean attribute `loading` // 해결: loading 속성 제거 후 조건부 렌더링으로 처리 const iconButtonProps: any = { onClick: () => { deleteFileMutation.mutate(image.name); }, color: "red", children: deleteFileMutation.isPending ? ( <Spinner {...spinnerProps} /> ) : ( <i className="fas fa-trash" /> ) }; 외부 라이브러리와의 통합 과정에서는 때로는 타입 시스템을 부분적으로 우회해야 할 필요가 있다는 것을 배웠습니다.미션 해결 회고기능에 집중을 하다가도...아무래도 빨간줄 에러표시가 뜨는 것이 저는 너무 신경이 쓰였던 것 같습니다. 중간중간마다 타입에러를 해결하는데 시간투자를 했었습니다. (ai에게도 많은 질문을 했습니다)저는 결국, 에러 무시하는 방법 혹은 TypeScript를 사용하여 타입 안전한 코드를 작성하는 방법 중 타입스크립트를 적용해보는 것을 선택했습니다.틈틈이 타입스크립트 공부도 해야할 것 같습니다.이번 풀스택 강의가 끝나고 나서 컴포넌트 안에서 공통으로 적용하여 재사용가능한 타입으로 빼서 리팩토링 할 시간도 가져보면 좋을 것 같습니다.그리고 프로젝트를 진행하면서 업로드 날짜 표시 기능과 한글 파일명 변환하는 작업은 하지 못한 점은 아쉬움으로 남습니다. 다른 수강생분들은 강의 따라하는 것 외에 새로운 추가 기능도 넣기도 한 것 같은데 저는 기본을 따라 가는 것에도 벅차서 추가적인 기능은 넣지 못했습니다..복습을 좀 더 해서 빠르게 지나쳤던 용어나 코드들을 재점검해야 할 것 같습니다... 감사합니다.

프론트엔드dropboxsupabase

채널톡 아이콘