← 전체 글로 돌아가기

Next.js

Next.js 폼의 상태가 제대로 초기화되지 않을 때

폼 상태 관련 버그는 보통 초기값 설정이나 리렌더링 시점에서 비롯된다. 원인을 빠르게 찾는 방법을 정리했다.

폼을 다루다 보면 상태가 초기화되지 않거나, 입력값이 남아있거나, 제출 후에도 폼이 비워지지 않는 일이 생긴다. 이런 문제는 대개 초기값 설정이나 상태 관리의 시점 문제다.

먼저 브라우저 개발자도구에서 상태를 본다

React DevTools를 켜서 실제 상태값이 뭔지 확인한다. "비워진 것처럼 보이지만" 실제로는 값이 남아있을 수 있다.

const [formData, setFormData] = useState({
  name: '',
  email: ''
})

React DevTools에서 이 상태를 확인하면 초기값이 제대로 설정됐는지 알 수 있다.

초기값을 명확히 정의한다

상태를 정의할 때 초기값을 명시적으로 써야 한다.

const INITIAL_FORM = {
  name: '',
  email: '',
  message: ''
}

const [formData, setFormData] = useState(INITIAL_FORM)

하드코딩하는 것도 명확하지만, 상수로 분리하면 재사용하기 쉽다.

제출 후 초기화 로직을 확인한다

폼 제출 후에 상태를 초기화해야 하는데, 이 부분이 빠질 수 있다.

const handleSubmit = async (e) => {
  e.preventDefault()

  // 데이터 제출
  await fetch('/api/form', {
    method: 'POST',
    body: JSON.stringify(formData)
  })

  // 제출 후 상태를 초기화한다
  setFormData(INITIAL_FORM)
}

제출이 성공했을 때만 초기화하려면 응답을 확인 후에 초기화한다.

폼 라이브러리를 쓴다면 라이브러리 문제인지 확인한다

react-hook-form이나 Formik을 쓰고 있다면, 라이브러리의 초기화 메서드를 제대로 쓰고 있는지 확인한다.

const { handleSubmit, reset } = useForm({
  defaultValues: INITIAL_FORM
})

const onSubmit = async (data) => {
  await fetch('/api/form', { method: 'POST', body: JSON.stringify(data) })
  reset() // 라이브러리의 초기화 함수
}

라이브러리마다 초기화 방식이 다르니 문서를 확인하자.

부모 컴포넌트에서 상태를 관리한다면 props를 확인한다

폼이 제어 컴포넌트라면, 부모에서 상태를 내려주고 있을 것이다.

// 부모
const [formData, setFormData] = useState(INITIAL_FORM)

return <FormComponent data={formData} onChange={setFormData} />

// 자식
const FormComponent = ({ data, onChange }) => {
  return (
    <input
      value={data.name}
      onChange={(e) => onChange({ ...data, name: e.target.value })}
    />
  )
}

Props로 내려주는 값이 제대로 초기화되는지 확인한다.

콘솔에 경고가 있는지 확인한다

상태 관련 경고나 에러가 콘솔에 나타나지는 않나? 특히 제어 컴포넌트와 비제어 컴포넌트를 섞으면 경고가 나온다.

캐시된 값이 아닌지 확인한다

API 응답을 캐싱하고 있다면, 캐시 때문에 UI가 제대로 업데이트되지 않을 수 있다. Next.js의 revalidate 시간을 확인하거나, 클라이언트 캐싱을 비활성화해본다.

결론

폼 상태 문제는 보통 초기값 미설정이거나 초기화 로직이 빠졌을 때 생긴다. 상태가 "무엇"인지 확인한 후, "어디서" 초기화해야 하는지 찾으면 대부분 해결된다.