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

IBBI·2024년 6월 25일
3

nextJS

목록 보기
4/5

이전 포스팅에서 이미지 파일을 input으로 받아서 화면에 띄우는 것까지 해보았다.
👉 이전 포스팅 보러가기
이번 포스팅에서는 이미지 파일을 FormData 객체로 생성한 formData 변수에 담아서 서버에 POST해보자!
레츄고~🍀


🍀 구현해보기

이전 포스팅에서 만들어놓은 ThumbnailBox 컴포넌트에 setThumbnail을 props로 넘겨줘서 이미지 file을 가져온다.

ThumbnailBox.tsx

interface ThumbnailBoxProps {
  setThumbnail: (file: File) => void;
}

function ThumbnailBox({ setThumbnail }: ThumbnailBoxProps) {
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [showImageUrl, setShowImageUrl] = useState<string | null | undefined>("");

  const handleImageChange = async (event: ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];

    if (file) {
      const imageUrl = URL.createObjectURL(file);
      setShowImageUrl(imageUrl);
      setThumbnail(file);
    }
  };

AddProjectContainer.tsx

ThumbnailBox.tsx를 불러오는 상위 컴포넌트이다.

function AddProjectContainer() {
  // formValues 상태를 정의하여 입력 폼의 값을 관리
  const [formValues, setFormValues] = useState({
    title: "",
    introduction: "",
    thumbnail: new File([], ""), // 썸네일 이미지 파일을 저장할 상태
  });

  // 폼 제출 핸들러 함수
  const handleFormSubmit = async (event: FormEvent<HTMLFormElement | HTMLButtonElement>) => {
    event.preventDefault();

    // FormData 객체를 생성하여 파일 및 기타 데이터를 전송할 준비 완
    const formData = new FormData();

    // 프로젝트 요청 데이터를 객체로 생성
    const projectRequestDto = {
      title: formValues.title,
      introduction: formValues.introduction,
    };

    // projectRequestDto 객체를 JSON 형태로 FormData에 추가
    formData.append(
      "projectRequestDto",
      new Blob([JSON.stringify(projectRequestDto)], {
        type: "application/json",
      })
    );

    // 썸네일 파일을 FormData에 추가
    formData.append("thumbnail", formValues.thumbnail);

    try {
      // postMutation을 사용하여 서버에 FormData 전송
      await postMutation.mutateAsync(formData);
      console.log("Project uploaded successfully");
    } catch (error) {
      console.error("Error occurred during mutation", error);
    }
  };

  return (
    // 폼 요소로 폼 제출 이벤트 핸들러를 설정
    <form onSubmit={handleFormSubmit} encType="multipart/form-data">
      {/* 섹션: 썸네일 업로드 */}
      <section className="flex w-fit flex-col gap-4">
        <Title title="썸네일" />
        <ThumbnailBox setThumbnail={thumbnail => setFormValues(prevState => ({ ...prevState, thumbnail }))} />
      </section>
	  {/* 등록 버튼 */}
      <Button type="submit" buttonSize="normal" bgColor="yellow">
          등록
      </Button>
    </form>
  );
}


🤔 이즈미 느낀점

일반 JSON 데이터와 이미지 파일 데이터를 한 번에 묶어서 어떻게 보내야 하는지 고민을 많이 했던 것 같다. 정말 많은 예시 코드들과 블로그들을 살펴보았고, 결국은 POST하는 것에 성공했다~!
프로젝트 도중 이 부분에서 오랜 시간 막혀서 힘들었는데 다행히 성공해서 기쁘다..🫠

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

0개의 댓글