Search
♾️

fix: useForm의 errors 속성의 값으로 {}를 넣으면 무한 랜더링이 발생하는 버그 수정

PR링크
레포
react-hook-form
상태
release 완료
유형
단순 버그 수정

레포지토리 설명

폼 데이터 관리 관리를 위한 도구들을 제공하는 react-hook-form

ISSUE 링크

12599
issues

PR링크

문제 상황

useFormerrors 속성의 값으로 {}를 넣으면 무한 랜더링이 발생하는 상황
export const FormAmountShowcase = () => { const formProps = useForm<{ foo: string }>({ defaultValues: { foo: "bar" }, errors: {}, }); return ( <FormProvider {...formProps}> <FormComp /> </FormProvider> ); };
JavaScript
복사
재현 링크 ( 무한 랜더링 발생 주의)

원인 파악

useForm.ts에서 errors가 쓰이는 곳은 두군데였다
함수 상단에 props로 들어온 error를 받아 state를 선언해주고
useEffect에서 _setErrors 메서드를 통해 업데이트를 해주는데 쓰이고 있다
// useForm.ts export function useForm< // ... >( // ... const [formState, updateFormState] = React.useState<FormState<TFieldValues>>({ // ... errors: props.errors || {}, // ... }); // ...
JavaScript
복사
// ... React.useEffect(() => { if (props.errors) { control._setErrors(props.errors); } }, [props.errors, control]); // ...
JavaScript
복사

해결방안

무한 랜더링을 막기 위해 빈 객체{} 가 아닐 때만 세터함수가 실행되도록 하였다
React.useEffect(() => { if (props.errors && Object.keys(props.errors).length > 0) { control._setErrors(props.errors); } }, [props.errors, control]);
JavaScript
복사
이미 프로젝트에 동일한 로직으로 체크하는 유틸함수가 있다는 코멘트를 받아 적용하였다.
React.useEffect(() => { if (props.errors && !isEmptyObject(props.errors)) { control._setErrors(props.errors); } }, [props.errors, control]);
JavaScript
복사

느낀점

테스트가 많고 체계적이라 배울점이 많았다.
기여하면서 케이스에 대해 공부하면 학습에도 많은 도움이 될 것 같았다
cypress를 통한 e2e 테스트와 jest, RTL을 통한 유닛, 통합 테스트가 모두 있어서 체계적으로 관리된다는 인상을 받았다
React-Hook-Form에 첫 PR이라 너무 서둘렀던 것 같다
isEmptyObject의 존재는 작업을 하면서 생각했었는데 까먹고 그냥 작성하였다;;
{} 외에도 다른 값들의 대해서도 조금 더 테스트를 해봤으면 좋았을 것 같다
{} 가 채워진 프로퍼티라고 해도 랜더링이 반복되는 것은 매한가지이다
useForm이 선언 된 스코프 밖에서 상수로 선언하면 문제는 해결 되겠지만
유저의 기대치와는 조금 동떨어진 방식이라는 느낌을 받았다.
errors prop이 그 특성상 자주 활용하지 않는다는 면에서 소외되어 있다는 느낌을 받았다