FE

react-hook-form의 register onChange 다루기

jvn4dev 2024. 8. 22. 01:51

기존의 input에 { …register } 방식으로 사용하다가, 수수료를 설정해야하는 input에 요구사항에 맞게 onBlur 이벤트를 사용해야할 부분(빈스트링이 들어갔다면 해당 수수료를 0으로 설정)이 있어 register api가 내장하고 있는 onBlur가 덮어씌워지지 않도록 ref, onChange, name 을 별도로 구조분해할당하여 사용하였다.

문제 발생

기존에 라이브나 마이그레이션 당시 왜 문제가 발생하지않았는지 의문이지만, 후원설정 토글을 on으로 설정한 뒤 form의 isDirty가 true가 되어 설정의 저장버튼이 활성화된 시점에서 수수료의 값을 변경하니 form이 변경되어 활성화되어있던 저장버튼이 비활성화가 돼버리는 문제가 발생했다.

트러블슈팅

우선 가정할 수 있는 상황은 다음과 같았다.

  1. form의 수수료 필드에 대한 스키마가 변경점(onChange)을 인지하지 못함.
  2. formState의 error가 발생하여 변경된 form을 저장할 수 없는 상황

우선 첫번째의 경우, 수수료를 변경한 뒤 저장 버튼이 비활성화되어 있더라도 설정 내 다른 탭으로 이동하려고 하면 변경된 내용이 있을 때 띄우는 alert모달이 팝업되는 것을 확인하였다.

이건 form이 제대로 변경된 값을 인지하고 있다는 뜻. 그래도 확실하지 않으니 해당 수수료필드의 register의 옵션으로 onChange로 확인해보았다.

const { ref, onChange, name } = register('donationFee', {
  onChange: event => {
    console.log(event.target.value);
  },
});

이렇게 확인했을 때 확실하게 값이 변경되고 있는 부분을 확인하였다.

그렇다면 첫번째 가설은 아니고, 두번째를 확인해본다.

저장버튼 액션을 담당하는 SubmitAction 컴포넌트에서 formState의 errors객체를 확인해보았는데 수수료가 변경되는 시점에 error가 발생하고 있었다.

message: "Expected number, received string"

이미 사용하고 있는 Input 공통컴포의 type은 number였지만 DOM input의 target.value는 string일테고 해당 value가 form에 등록되려는 듯 해보였다.

이를 해결하기 위해 register옵션으로 valueAsNumber true로 설정하였다.

const { ref, onChange, name } = register('donationFee', {
  valueAsNumber: true,
});

이제 정상적으로 변경점을 인지했을 때 저장 버튼이 활성화되는 모습을 확인할 수 있었다.