Next.js
React 폼 상태를 한 객체로 묶었다가 검증을 나눈 이유
체크박스의 false 값이 서버에 전달되지 않던 폼 오류를 상태와 검증 규칙으로 분리한 회고입니다.
저장했는데 알림 설정이 돌아왔다
프로필에서 닉네임을 바꾸고 알림을 끄면 닉네임만 저장됐다. 화면에는 두 값이 모두 바뀌었지만, value || undefined로 만든 요청 데이터가 false를 누락 값으로 바꾸고 있었다. false와 아직 입력하지 않은 undefined를 구분하지 않은 것이 원인이었다.
화면 상태는 입력을 그대로 담는다
const [form, setForm] = useState({ nickname: initial.nickname ?? '', marketing: !!initial.marketing });
const update = (name, value) => setForm((current) => ({ ...current, [name]: value }));
<input value={form.nickname} onChange={(e) => update('nickname', e.target.value)} />
<input type="checkbox" checked={form.marketing} onChange={(e) => update('marketing', e.target.checked)} />
입력 상태에는 빈 문자열, false, 0도 남겨야 한다. 전송 직전 변환은 별도의 검증 뒤에 실행한다.
function validateProfile(value) {
const errors = {};
if (value.nickname.trim().length < 2) errors.nickname = '두 글자 이상 입력하세요.';
return errors;
}
const errors = validateProfile(form);
if (Object.keys(errors).length === 0) {
await fetch('/api/profile', { method: 'PATCH', headers: {'Content-Type':'application/json'}, body: JSON.stringify({ nickname: form.nickname.trim(), marketing: form.marketing }) });
}
남긴 테스트 기준
- 체크박스를 켰다 끄면 본문에
false가 있는가 - 공백 닉네임이 요청 전에 막히는가
- 오류가 다른 입력값을 지우지 않는가
- 실패 후 사용자의 입력이 보존되는가
폼 상태와 API 계약을 분리하니 조건부 필드를 추가해도 값의 의미가 흔들리지 않았다.