일반적인 html의 form은 사용자로부터 데이터를 입력받고, 데이터를 전송할 GET / POST 메소드 등을 설정한다. 그 후 action 속성에는 폼 데이터를 전송한 뒤 전환할 화면의 URL을 설정하는 방식으로 사용한다. 하지만 react와 같은 SPA 방식 프론트엔드 라이브러리 / 프레임워크를 사용할 때는 백엔드 웹 서버가 API 방식으로 동작하므로 굳이 이렇게 구현할 필요가 없다.
react에서 form 데이터를 서버로 처리하는 방법에는 여러가지가 있다. 그중 하나인 FormData
를 사용하는 방법에 대해 알아보자.
FormData
는 js 엔진이 기본으로 제공하는 클래스로서, 사용자가 <form>
안에 입력한 데이터들을 웹 서버에 전송할 목적으로 사용된다. react에서는 주로 파일 업로드와 같이 폼 데이터를 처리하거나 AJAX 요청을 활용한다. 아래는 React에서 FormData
를 활용하는 예시이다.
import React, { useState, FC, ChangeEvent, FormEvent } from 'react';
const FormDataExample: FC = () => {
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const [value, setValue] = useState<string>('');
const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {
setSelectedFile(event.target.files![0]);
};
const handleUpload = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault(); // 새로고침을 방지해준다.
if (selectedFile && value) { // 선택된 파일과, form의 data가 있을 시에만 적용 함으로써 잠재적 버그 방지
const formData = new FormData();
formData.append('file', selectedFile);
formData.append('value', value);
//
fetch('지정된 서버 url로 전송', {
method: 'POST',
body: formData
})
.catch(error => console.error('Error uploading file:', error));
}
};
return (
<form onSubmit={handleUpload}>
<input value={value} onChange={(e) => setValue(e.target.value)}/>
<input type="file" onChange={handleFileChange} />
<button type='submit'>Upload</button>
</form>
);
}
export default FormDataExample;
FormData
의 인스턴스를 만들고, 그곳에 append()
함수를 이용해 넣고 싶은 데이터를 key
값과 함께 넣어준다. 이렇게 넣어준 데이터는 서버에서 request의 body
에서 확인할 수 있다.
다음으로 FormData
의 주요 메서드를 살펴보자.
append(name: string, value: any, fileName?: string): void
지정한 이름으로 필드와 값을 추가한다. fileName
은 파일 필드에 사용되는 경우 이름을 지정한다.
delete(name: string): void
지정한 이름의 필드와 값을 삭제한다.
get(name: string): FormDataEntryValue | null
지정한 이름의 필드 값을 가져온다.
etAll(name: string): FormDataEntryValue[]
지정한 이름의 모든 필드 값을 가져온다.
has(name: string): boolean
지정한 이름의 필드가 존재하는지 여부를 확인한다.
만약 FormData
의 내용을 JSON 포멧으로 바꾸고 싶다면 js에서 기본적으로 제공하는 Object.fromEntries()
함수를 아래와 같이 호출하면 된다.
const json = Object.fromEntries(formData);