서버에서 HTML을 생성해 웹 브라우저 쪽에 전송하는 전통 방식의 웹 개발에서는 사용자에게 데이터를 받을 때 <form> 요소를 사용한다. 이때 폼 요소는 method 속성에 HTTP 메서드를 설정하고, action 속성에는 폼 데이터를 전송한 뒤 전환할 화면의 URL을 설정하는 방식으로 사용한다. 만일 method 설정값이 POST 라면 폼 데이터를 암호화하는 다음 3가지 방식 중 하나를 encType 속성에 설정한다.
- application/x-www-form-urlencoded(기본값)
- multipart/form-data
- text/plan
하지만 리액트와 같은 SPA 방식은 백엔드가 API 방식으로 동작하므로 굳이 폼 요소와 속성등을 설정할 필요가 없다. 다만 관습적으로 사용자 입력을 받는 부분을 <form> 요소로 구현한다.
버튼 이벤트 예제
import type {FormEvent} from 'react'
... 생략 ...
const onSubmit = (e: FormEvent<HTMLFormElement>) => {}
<form onSubmit={onSubmit}>
<input type="submit" value="버튼_텍스트" />
</form>
브라우저는 onSubmit 이벤트가 발생하면 <form> 이 있는 웹 페이지를 다시 렌더링 한다. 이 때문에 onSubmit을 구현할 때는 반드시 e.preventDefault()를 호출해 웹페이지가 다시 렌더링 되지 않도록 해야한다.
FormData 클래스
FormData 클래스는 JavaScript에서 제공하는 인터페이스로, 웹 애플리케이션이 서버로 데이터를 전송할 때 HTML 폼의 데이터와 동일한 형식으로 데이터를 쉽게 구성할 수 있게 한다.
생성자
- FormData(): 빈 FormData 객체를 생성한다.
- FormData(form): 주어진 HTMLFormElement 객체로부터 데이터를 초기화한다.
주요 메서드
- append(name, value, filename): 폼 데이터에 새로운 키-값 쌍을 추가한다. 파일을 추가할 경우 filename을 지정할 수 있다.
- delete(name): 주어진 이름의 모든 키-값 쌍을 삭제한다.
- get(name): 주어진 이름의 첫 번째 값을 반환한다.
- getAll(name): 주어진 이름의 모든 값을 배열로 반환한다.
- has(name): 주어진 이름의 키가 존재하는지 여부를 확인한다.
- set(name, value, filename): 주어진 이름의 값을 업데이트하거나 존재하지 않으면 새로 추가한다.
Form 사용 예제
import type {ChangeEvent, FormEvent} from 'react'
import {useCallback, useState} from 'react'
import {Title} from '../components'
import {Input} from '../theme/daisyui'
type FormType = {
name: string
email: string
}
export default function FormExample() {
const [form, setForm] = useState<FormType>({name: '', email: ''})
const onSubmit = useCallback(
(e: FormEvent<HTMLFormElement>) => {
e.preventDefault()
alert(JSON.stringify(form, null, 2))
},
[form]
)
const onChangeName = useCallback((e: ChangeEvent<HTMLInputElement>) => {
setForm(form => ({...form, name: e.target.value}))
}, [])
const onChangeEmail = useCallback((e: ChangeEvent<HTMLInputElement>) => {
setForm(form => ({...form, email: e.target.value}))
}, [])
return (
<section className={'mt-4'}>
<Title>BasicForm</Title>
<div className={'flex justify-center mt-4'}>
<form onSubmit={onSubmit}>
<div className={'form-control'}>
<label className={'label'} htmlFor={'name'}>
<span className={'label-text'}>Username</span>
</label>
<Input
value={form.name}
onChange={onChangeName}
id={'name'}
type={'text'}
placeholder={'enter your name'}
className={'input-primary'}
/>
</div>
<div className={'form-control'}>
<label className={'label'} htmlFor={'email'}>
<span className={'label-text'}>email</span>
</label>
<Input
value={form.email}
onChange={onChangeEmail}
id={'email'}
type={'email'}
placeholder={'enter your email'}
className={'input-primary'}
/>
</div>
<div className={'flex justify-center mt-4'}>
<input
type={'submit'}
value={'SUBMIT'}
className={'w-1/2 btn btn-sm btn-primary'}
/>
<input
type={'button'}
defaultValue={'CANCEL'}
className={'w-1/2 ml-4 btn btn-sm'}
/>
</div>
</form>
</div>
</section>
)
}
728x90
'Javascript > React' 카테고리의 다른 글
컴포넌트 생명 주기와 useEffect, useLayoutEffet (0) | 2024.07.14 |
---|---|
깊은 복사와 얕은 복사, 그리고 의존성 목록 (0) | 2024.07.13 |
[React] DetailedHTMLProps와 HTMLAttributes 이해하기 (0) | 2024.06.29 |
[React] PropsWithChildren 이해하기 (0) | 2024.06.19 |
styled-components에서 $ 접두사 사용하기 (0) | 2024.06.01 |