React 에서 formData 다루기

 

React 에서 이진 형태의 이미지를 서버로
보내기 위해서는 특별한 형태로 보내야 합니다.

 

왜 특별한 형태로 서버로 전송되는가?


일반적인 텍스트 데이터는 문자열 형태로 이루어져 있어서, 데이터를 인코딩하고 디코딩하는 과정에서 문자 집합 및 특수 문자 등을 다루는 것이 비교적 간단하지만 이미지나 다른 바이너리 파일은 이진 형태로 이루어져 있습니다.  즉, 이 데이터는 텍스트가 아닌 이진 형태의 바이트로 구성되어 있습니다. 따라서 이진 데이터를 전송할 수 있는 특별한 형태의 인코딩이 필요합니다. 그래서 axios 에 이진 데이터를 전송할 때 도와주는 multipart/form-data 형식을 주로 사용하게 됩니다.  이 형식은 여러 종류의 데이터를 구분하여 전송할 수 있도록 도와줍니다.

 

간단한 용어 설명


프론트에서 서버로 파일,이미지를 보낼 때는 특별한 방법을 사용해야 합니다.

아래 코드는 이미지 파일을 서버에 전송하기 위한 특별한 형태의 데이터 상자를 만드는 명령어 입니다.

const formData = new FormData();

 


FormData는 데이터를 특별한 형식으로 묶어서 전송할 때 사용 되는 객체입니다. 
이를 사용하면 서버로 여러 종류의 데이터를 쉽게 전송할 수 있습니다. 
여기서는 이미지 파일을 전송하기 위해 사용됩니다.

우리가 만든 formData 를 이용해 서버로 이미지를 보내기 위해서는 formData 에 이미지를 넣어 주어야 합니다.

아래 코드는 만든 데이터 상자에 이미지를 넣는 것입니다. 이렇게 하면 나중에 서버가 이미지를 찾아서 받아줄 수 있습니다. 
'file'이라는 이름을 사용해서 서버에서 이 데이터를 찾아낼 수 있습니다.

formData.append('file', image);


append 메서드는 FormData에 데이터를 추가하는 역할을 합니다. 
여기서는 선택한 이미지 파일(image)을 'file'이라는 이름으로 추가하고 있습니다

 

이 코드를 사용하는 이유

  • 1. 파일 전송이 특별한 형태로 이루어져야 함
    일반적인 텍스트 데이터와는 달리 이미지나 다른 바이너리 파일은 특별한 형태로 서버로 전송되어야 합니다. 
    FormData는 이를 간단하게 처리할 수 있는 도구입니다.

 

  • 2. 서버가 어떤 데이터인지 이해할 수 있어야 함
    서버는 클라이언트로부터 받은 데이터를 해석하고 처리해야 합니다. 
    'file'이라는 이름을 통해 서버는 클라이언트가 보낸 파일 데이터를 식별하고, 이를 적절히 처리할 수 있습니다.


file 을 보내기 위한 input 구조

input 을 이용해 file 을 다루기 위해서는 아래 코드처럼 만들어 주시면 됩니다.

<input type="file" accept="image/*" onChange={handleFileChange} />


accept 는 무엇일까요? 간단하게 말하면 어떤 파일 형식을 허용할 것인지 결정해 주는 코드입니다.
위에 보이는 코드는 모든 image 형식을 허용한다고 정해준 것이고 만약 jpg, png 만 허용하고 싶다면 밑에 코드처럼 쓰면 됩니다.

<input type="file" accept="image/jpeg, image/png" />

 

 

기본 사용법

// 한개의 이미지 파일 보내기

const [file, setFile] = useState<File | null>(null);

const fileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
	if(e.target.files && e.target.files.length > 0) {
		setFiles(e.target.files[0]);
	}
}

const formData = newFormData();
formData.append("file", image);

<input type="file" accept="image/*" />
<input type="file" accept="image/jpeg, image/png" />

 

기본적으로 두 코드는 전부 tsx 를 기준으로 만든 코드들 입니다.

// 두개 이상의 파일 보내기

const [files, setFiles] = useState<FileList | null>(null);

const fileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
	if(e.target.files && e.target.files.length > 0) {
		setFiles(e.target.files);
	}
}

const formData = newFormData();
Array.from(files).map(file => {
	formData.append("files", file)
})

<input type="file" accept="image/*" multiple />

 

console.log 로 찍어보기

 

files 라는 변수 안에 이미지를 2개 이상 저장하고 출력하면 아래와 같은 구조가 나옵니다.

 

이러한 구조를 바로 formdata 를 이용해서 넣어줄 수는 없습니다. 

따라서 이러한 FileList 를 리스트 형식으로 담아주어야 서버로 보내줄 수 있습니다. 

Array.from 을 이용해서 FIleList 를 넣어주고 console.log 로 찍어보면 아래와 같은 사진처럼 나옵니다.

 

이걸 이용해서 아래와 같은 코드로 짜면 서버로 보낼 준비가 된 것입니다.

const formData = newFormData();
Array.from(files).map(file => {
	formData.append("files", file)
})

'React' 카테고리의 다른 글

React 에러 핸들링  (1) 2024.09.10
메뉴 밑줄 슬라이딩 만들기  (0) 2024.08.26
useId  (0) 2024.08.19
useLayoutEffect  (0) 2024.08.13
React-throttle  (0) 2024.08.12