아래를 보면, onSubmit 이벤트를 사용하여 인풋에 입력한 value값을 콘솔로 출력하기 위한 코드를 작성했으나 예상과 달리 아무런 값도 출력되지 않습니다. 무엇이 문제일까요?
원인은 handleSubmit 함수에 e.preventDefault();
를 추가해주지 않았기 때문입니다.
import { useState } from 'react';
function ReviewForm() {
const [title, setTitle] = useState('');
const handleTitleChange = (e) => {
setTitle(e.target.value);
};
const handleSubmit = (e) => {
console.log({
title
});
};
return (
<form className="ReviewForm" onSubmit={handleSubmit}>
<input value={title} onChange={handleTitleChange} />
<button type="submit">확인</button>
</form>
);
}
그렇다면, 왜 e.preventDefault();
를 추가해서 기본 동작을 방지해줘야 할까?
html에서 form 태그의 기본 동작은 type이 submit인 버튼을 눌렀을 때 입력 폼의 값과 함께 서버에 get 리퀘스트를 보내는 것이기 때문입니다. (폼 데이터를 서버로 전송하고 페이지를 다시 로드하는 동작 수행)
따라서 서버로 데이터를 전송하고 싶지 않거나 기타 원하는 동작을 수행하기 위해서는 기본 동작을 중지해주어야 합니다.
자주 쓰는 이유 -> 새로고침 방지
여기서 event.preventDefault()
를 사용하는 이유는 폼 제출의 기본 동작이 페이지를 다시 로드하고 새로고침하기 때문입니다. 따라서 새로고침과 동시에 입력했던 정보를 분실하는 문제가 발생합니다. 이러한 문제를 막고 싶을 때 preventDefault()
를 사용하면 좋습니다.
예를 들어, 보통 사이트에 회원가입을 하면, form 제출과 동시에 페이지가 새로 고침 되기 때문에 다시 이메일과 비밀번호를 입력해야 하지만, preventDefault()
를 쓰면 새로고침을 막을 수 있어서 그 이후의 작업 처리가 가능합니다. 따라서 재로그인할 필요 없이 바로 로그인된 상태로 넘어갈 수 있습니다.
(이 밖에도 입력한 값을 화면의 특정 공간에 표시한다던지 등, 서버에 데이터를 보내거나, 새로고침할 필요가 없는 상황에서 자주 씁니다)
<form>: 사용 측에서 입력을 입력하는 HTML 양식을 정의
<input>: 입력 컨트롤을 정의
<textarea>: 다중 라인 입력 컨트롤을 정의
<label>: 입력 요소의 레이블을 정의
<fieldset>: 관련 요소를 양식으로 그룹화
<legend>: <fieldset> 요소에 대한 캡션을 정의
<select>: 드롭다운 목록을 정의
<optgroup>: 드롭다운 목록에서 관련 옵션 그룹을 정의
<option>: 드롭다운 목록에서 옵션을 정의
<button>: 클릭 가능한 버튼을 정의
→ 폼 요소는 자체적으로 양식을 생성하는 것이 아니라 <input>, <label>
등과 같은 필수 양식 요소를 포함하는 컨테이너!