react query useMutation으로 FormData 요청 보내기

이예빈·2022년 11월 16일
3
post-thumbnail

React Query(TanStack Query)에서 서버에 create, update, delete 요청을 보내야 하는 경우 useMutation을 이용한다.

프로젝트 진행중 이미지를 서버로 업로드하기 위해 formdata를 전송해야 하는 상황이었다. 서버에서는 이미지를 받아서 S3에 저장 후 url을 응답으로 보내준다.

우선 headers에 'Content-Type': 'multipart/form-data'를 설정해주어야 한다. Content-Type은 HTTP 요청에서 Message Body에 들어가는 데이터의 타입을 명시해주는 필드이다.

const config = {
	headers: { 'Content-Type': 'multipart/form-data' },
};

요청 코드를 단순화 하기 위해 우선 config이라는 변수로 따로 선언을 해 주었다.

그리고 axios를 이용해 서버로 formdata를 전송해주는 훅을 만들었다.

const useGetPhotoUrl = () => {
	return useMutation(
		(formData: FormData): Promise<AxiosResponse> =>
			axiosInstance.post(`/upload`, formData, config),
	);
};

서버 URL을 포함하여 별도로 생성해둔 axiosInstance에 post 요청으로 endpoint와 formdata, 위에 적어둔 config을 포함시킨다.

초반에 formdata를 body data로 포함시켜야한다고 생각해서 data: formData로 작성했더니 계속 파일이 요청에 포함되지 않아서 고생했던 기억이 난다..

사진을 첨부하는 컴포넌트에서 이제 작성한 훅을 사용만 하면 된다.

const { mutate } = useGetPhotoUrl();

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
		const { files } = e.target;
		const formData = new FormData();
		if (files) {
			const fileRef = files[0];
			resizeImageToBlob(fileRef).then((blob: Blob) => {
				formData.append('img', blob);
				mutate(formData, {
					onSuccess: res =>
						dispatch(updateRentalInfo({ key: 'imageUrl', value: res.data })),
				});
			});
		}
	};

이미지가 input에 업로드 되었을 때 실행되는 handleChange 함수이다.
resizeImageToBlob이라는 함수를 먼저 수행하여 이미지의 용량을 줄여주고 생성한 FormData에 추가(append)해준다.

useGetPhotoUrl 훅에서 구조분해할당으로 가져온 mutate 함수에 최종적으로 이미지가 담긴 formdata를 전달해주면 서버로 이미지가 잘 전송이 된다.

profile
temporary potato

0개의 댓글