[nextJS] 이미지 업로드 레츠고(1)

IBBI·2024년 6월 17일
2

nextJS

목록 보기
3/5

프로젝트 업로드 페이지에서 필요한 이미지 업로드 및 수정하는 기능을 구현하려 한다.

🍀 구현 시 생각해봐야 할 것

구현을 시작하기 전에 해당 사이트(또는 페이지)의 요구사항과 목표를 명확히 이해하고 시작하는 것이 중요한 것 같다.

1️⃣ 업로드 버튼 클릭한 후 이미지 업로드하기

2️⃣ 해당 영역에 이미지 띄우기

3️⃣ 수정 버튼 클릭 후 새로운 이미지 업로드하기


🍀 구현해보기

📌 기본 - NextJS, TypeScript
📌 디자인 - Tailwind CSS

function ThumbnailBox() {
  // 파일 입력 참조 생성
  const fileInputRef = useRef<HTMLInputElement>(null);
  // 이미지 URL 상태 관리, 초기값은 빈 문자열
  const [showImageUrl, setShowImageUrl] = useState<string | null | undefined>("");

  // 파일 입력 변화 핸들러, 파일을 URL로 변환하여 상태에 저장
  const handleImageChange = async (event: ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0]; // 업로드할 이미지 파일은 1개이므로 첫 번째 파일을 가져옴

    if (file) {
      const imageUrl = URL.createObjectURL(file); // 파일 객체를 URL로 변환
      setShowImageUrl(imageUrl); // 이미지 URL 상태 업데이트
    }
  };

  // 업로드 버튼 클릭 핸들러, 숨겨진 파일 입력 클릭
  const handleUploadButtonClick = () => {
    if (fileInputRef.current) {
      fileInputRef.current.click(); // 파일 입력 요소 클릭
    }
  };

  return (
    <div className="flex flex-col items-center">
      <div className="relative flex h-[232px] w-[232px] items-center justify-center rounded-xl border-2 border-dashed border-gray-200 bg-gray-100">
        {showImageUrl ? (
    	  {/* 이미지를 업로드한 경우 이미지와 버튼 표시 */}
          <div className="group relative h-full w-full">
            <Image fill className="rounded-xl object-cover" src={showImageUrl} alt="썸네일 이미지" />
            {/* hover 시 반투명 오버레이 */}
            <div className="absolute inset-0 bg-gray-200 opacity-0 transition-opacity duration-300 group-hover:opacity-50" />
            {/* hover 시 이미지 수정 버튼 표시 */}
            <div className="absolute inset-0 flex items-center justify-center opacity-0 transition-opacity duration-300 group-hover:opacity-100">
              <Button
                className="border border-solid border-blue-400 text-blue-500"
                buttonSize="normal"
                bgColor="white"
                onClick={handleUploadButtonClick}>
                이미지 수정
              </Button>
            </div>
          </div>
        ) : (
          {/* 이미지 업로드하지 않은 경우 업로드 버튼 표시 */}
          <Button
            className="border border-solid border-blue-400 text-blue-500"
            buttonSize="normal"
            bgColor="white"
            onClick={handleUploadButtonClick}>
            이미지 업로드
          </Button>
        )}
      </div>
	  {/* 실제로 파일을 업로드하는 숨겨진 input 요소 */}
      <input type="file" id="fileInput" ref={fileInputRef} className="hidden" onChange={handleImageChange} />
    </div>
  );
}

export default ThumbnailBox;


🤔 이즈미 느낀점

구현하기 전에는 어떻게 구현해야 할지 좀 막막했지만, 여러 참고 코드들을 살펴보고, 이전에 다른 팀원이 구현했던 코드들도 뜯어보면서 점차 감이 잡혔다.
역시 코드를 눈으로 보는 것보다 직접 짜보는 게 더 많은 것을 배우게 하는 것 같다.
직접 구현하면서 여러가지 문제를 마주하고 해결하는 과정에서 깊이 있는 이해를 할 수 있었고, 실전 경험이야말로 최고의 학습 방법임을 다시 한 번 느꼈다. 🫠

profile
IBBI의 말하는 감자 탈출 프로젝트

0개의 댓글