-
Notifications
You must be signed in to change notification settings - Fork 1
✨feat: ImageUpload 컴포넌트 구현 #95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Yun-Jinwoo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
확인했습니다! 고생하셨습니다~!👍
| value, | ||
| onChange, | ||
| }: ImageUploadProps) { | ||
| const fileInputRef = useRef<HTMLInputElement | null>(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오.. ts가 똑똑해서 자동 추론이 되는군요! 좋은 정보 감사합니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이미 generic으로 지정을 해서 추론은 아닐 거고, 원래 사용할 때 hook에서 기본적으로 null을 union type으로 포함한다고 보시면 될 거 같아요~
Moon-ju-young
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| onChange, | ||
| }: ImageUploadProps) { | ||
| const fileInputRef = useRef<HTMLInputElement | null>(null); | ||
| const [preview, setPreview] = useState<string>(value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| const [preview, setPreview] = useState<string>(value); | |
| const [preview, setPreview] = useState(value); |
💬 자동적으로 type 추론이 되어서 이렇게 적어도 될 것 같습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵 알겠습니다!
| setPreview(value); | ||
| }, [value]); | ||
|
|
||
| const handleButtonClick = () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💬 버튼이 아니기도 하고 다른 Click Event handler가 없어서 그냥 handleClick으로 이름을 해도 괜찮을 것 같습니다~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵 좋습니다!
| <label className="text-body1/26 font-regular text-black">{label}</label> | ||
|
|
||
| <div | ||
| onClick={handleButtonClick} | ||
| className="flex h-200 w-full cursor-pointer items-center justify-center rounded-xl border border-gray-30 bg-gray-10 md:h-276 md:w-483" | ||
| > | ||
| {preview ? ( | ||
| <img | ||
| src={preview} | ||
| alt="미리보기" | ||
| className="size-full rounded-xl object-cover" | ||
| /> | ||
| ) : ( | ||
| <div className="flex flex-col items-center gap-11"> | ||
| <img src={Camera} alt="카메라" className="size-32" /> | ||
| <span className="text-body1/20 font-bold text-gray-40"> | ||
| 이미지 추가하기 | ||
| </span> | ||
| </div> | ||
| )} | ||
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💬 이 부분에 대해선 개인차이긴 한데, 보통은 label을 이미지 미리보기로 많이 활용하는 편입니다! 기본적으로 label과 input을 연결해 주면 label을 눌렀을 때 input을 클릭했을 때와 동일한 동작을 보여서 label로 사용한다면 handleButtonClick 함수가 필요 없을 듯 합니다~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 좋은 방법이네요 한 번 바꿔보겠습니다!
| onChange: (file: File, previewUrl: string) => void; | ||
| } | ||
|
|
||
| export default function ImageUpload({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💬 이 역시 input의 한 종류라서 ImageInput 등 input이라는 이름을 포함하면 좋을 것 같습니다~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵 알겠습니다!
|
|
||
| export default function ImageUpload({ | ||
| label, | ||
| value, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ 기본 이미지 값을 나타내는 prop일까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵 맞습니다! 근데 이름이 좀 애매하니 value에서 imageUrl로 변경하겠습니다!
| interface ImageUploadProps { | ||
| label: string; | ||
| value: string; | ||
| onChange: (file: File, previewUrl: string) => void; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ 어떤 함수인지 잘 모르겠습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이미지를 바꾸는 함수인데 이름이 모호한 것 같네요 변경하겠습니다!
|
|
||
| <div | ||
| onClick={handleButtonClick} | ||
| className="flex h-200 w-full cursor-pointer items-center justify-center rounded-xl border border-gray-30 bg-gray-10 md:h-276 md:w-483" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💬 너비를 설정해야 한다면 상위 태그에서 조정하는 것이 맞을 것 같습니다! 그리고 w-full로 두거나 className을 받아서 상위에서 너비를 조절하게 한다면 더 좋을 것 같습니다~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵 알겠습니다!
| value, | ||
| onChange, | ||
| }: ImageUploadProps) { | ||
| const fileInputRef = useRef<HTMLInputElement | null>(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이미 generic으로 지정을 해서 추론은 아닐 거고, 원래 사용할 때 hook에서 기본적으로 null을 union type으로 포함한다고 보시면 될 거 같아요~
| const reader = new FileReader(); | ||
| reader.onloadend = () => { | ||
| const previewUrl = reader.result as string; | ||
| setPreview(previewUrl); | ||
| onChange(file, previewUrl); | ||
| }; | ||
| reader.readAsDataURL(file); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ 아마 배울 때는 URL.createObjectURL을 사용했던 것 같은데, FileReader를 쓰신 이유가 있으신가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아 그렇네요 까먹고 있었습니다! 바꾸도록 하겠습니다!


📌 변경 사항 개요
이미지 업로드 컴포넌트 구현
📝 상세 내용
가게 등록 페이지에 이미지를 등록할 수 있는 인풋 컴포넌트를 구현했습니다.
🔗 관련 이슈
🖼️ 스크린샷(선택사항)
💡 참고 사항