프론트엔드 개발을 하다 보면 폼(Form) 개발은 단순히 데이터를 입력받는 작업 이상임을 깨닫게 된다. 오케스트라 지휘자처럼 모든 데이터를 조화롭게 관리하고, 적절한 타이밍에 검증하며, 최종적으로 목적지까지 안전하게 데이터를 전달해야 하는 까다로운 작업이다. 하나의 악기라도 제대로 지휘하지 못하면 불협화음의 수렁에 빠지게 된다.
요즘은 react-hook-form
, formik
, yup
, zod
등 다양한 입력값 상태관리 및 유효성 검증 라이브러리들이 수렁에 빠진 개발자들을 돕고 있다. 하지만 자동차 운전을 배울 때 자동변속기만 고집하다 보면 수동변속기의 매력과 원리를 놓칠 수 있듯, 폼 라이브러리의 높은 추상화 수준에 익숙해지다보면 HTML form
요소의 기본기를 놓치기 쉽다. 주문서 개발을 하며 간과할 뻔 했던 form
요소의 기본 동작들을 정리했다.
❗ required
<form>
<input type="text" required pattern="[A-Za-z]{3,}" title="3글자 이상의 영문을 입력해주세요" />
<button type="submit">제출</button>
</form>
required
속성은 웹이 우리에게 준 가장 간단하면서도 강력한 검증 도구다. 경비원처럼 부적절한 입력값이 더 안쪽으로 들어가는 것을 막아준다. 이를 적절히 활용하지 못하면 쉽게 갈 수 있는 지름길을 두고 먼 길을 돌아가는 격이다. 특히 주목할 점은:
- HTML 기본 검증이 우선:
required
속성은 JavaScript로 작성한 커스텀 검증(validation)보다 먼저 동작한다. 예를 들어, 사용자가 입력 필드를 비워둔 상태로 제출 버튼을 누르면 브라우저가 곧장 오류를 표시한다. - 스크롤과 포커스 처리:
required
로 검증에 실패하면 브라우저가 자동으로 해당 입력 필드로 스크롤을 이동하고 포커스를 준다. 이 기능 덕분에 추가 코드 없이도 UX를 향상시킬 수 있다. - 실전 팁: 라이브러리로 검증하기 전에,
required
속성으로 기본적인 검증을 처리해보자. 예를 들어 생년월일 필드에 입력이 없는 경우, 라이브러리를 호출하기 전에 브라우저가 바로 경고를 표시할 수 있다. pattern
속성과 결합하면 기본적인 정규식 검증도 가능하다.
<input type="text" required pattern="\d{3}-\d{3,4}-\d{4}" title="전화번호는 010-1234-5678 형식으로 입력해주세요." />
💭 onInvalid
onInvalid
는 사용자에게 무엇이 잘못되었는지 알려주는 안내원으로, required나 pattern 검증이 실패했을 때 호출되어 사용자에게 적절한 가이드를 제공한다. 여러 개의 input
필드 중 유효하지 않은 필드에 커스텀 메시지를 표시하고 싶다면:
<form>
<input type="text" required oninvalid="this.setCustomValidity('이름을 입력해주세요!')" />
<input type="submit" />
</form>
위 코드에서 이름 필드를 비우고 제출을 누르면, 브라우저 기본 메시지 대신 "이름을 입력해주세요!"
라는 메시지가 표시된다.
🏁 Checkbox와 Label
<label htmlFor="agree">약관에 동의합니다</label>
<input type="checkbox" id="agree" />
체크박스는 단순히 클릭해서 선택하는 요소처럼 보이지만, 접근성 측면에서는 label
과의 조합이 필수다. 체크박스와 label
을 연결하면 클릭 범위가 체크박스 자체를 넘어 label
까지 확장되며 사용자 경험이 개선된다.
-
피해야 할 실수: 체크박스 상태를 감지하려고 관성적으로
onClick
을 사용하기 쉽다.checked
속성을 가진 이벤트는onChange
임을 기억하고 체크 상태를 확인하자.
<input type="checkbox" id="agree" onChange={(e) => console.log(e.target.checked)} />
얼마 전 <흑백요리사>를 볼 때 인상적이었던 점 중 하나는 가장 창의적이고 놀라운 요리를 선보이는 쉐프들은 또한 가장 정교하게 칼을 다루는 사람이라는 점이었다. 근사한 주방 기구들이 많이 있어도 기본적인 칼질을 모른다면 진정한 요리사가 될 수 없듯, HTML form 요소의 기본기를 충실히 다지고 그 위에 좋은 도구들을 적절히 활용할 때 진정한 Form 마스터가 될 수 있다. 이번 주문서 개발을 통해 브라우저 기본 동작을 많이 습득했기에, 다음 번에는 기획 과정에서부터 디폴트 동작을 적극적으로 활용할 수 있도록 이런 내용을 공유하고 제안해볼 수 있을 것 같아 기대가 된다.