나는 주로 input으로 인한 리렌더링이 많을 거라고 예상하였고 폼 위주로 분석해 보았다.
위 스크린샷은 프로필 편집 페이지에서 닉네임 인풋에 계속 타이핑하고 수정하기 버튼까지 누르는 걸 레코드 한 결과다.
FormProvider
, RadioGroup
, RovingFocusGroup
, Slot
등 여러 컴포넌트가 리렌더링되고 있다. 이 중 FormProvider
와 관련된 컴포넌트들이 자주 보이는데, 이는 폼 상태 관리 로직이 입력 변화에 민감하게 반응하고 있음을 나타낸다.• React DevTools의 "왜 리렌더링되었나요?" 기능을 활용하여 각 컴포넌트의 리렌더링 원인을 정확히 파악할 수 있다. 이 도구는 컴포넌트의 props 또는 state가 변경될 때 그 변경 사항과 함께 리렌더링된 이유를 상세히 알려 준다.
useCallback
으로 감싸서, 입력 값이 변경될 때만 함수가 재생성되도록 하였다.```tsx
const onSubmit = useCallback(
(values: ProfileFormValues) => {
updateProfile(user?.uid as string, values)
.then(result => {
if (result.success) {
openAlert('프로필이 수정되었습니다.', '');
setUser(result.user!);
} else {
openAlert('오류가 발생했습니다.', result.error as string);
}
})
.catch(error => {
openAlert('오류가 발생했습니다.', error);
});
},
[user?.uid, setUser, openAlert],
);
```
```tsx
function ProfileEmailInput({ loginType, email }: ProfileEmailInputProps) {
return (
<div className='flex flex-col space-y-2'>
{/* ... 생략 */}
</div>
);
}
export default React.memo(ProfileEmailInput);
```
개선 방안을 실행한 후 다시 프로파일링 해 본 결과다. 전에 비해 리렌더링 되는 컴포넌트가 확실히 줄어든 것을 확인할 수 있다.
현재 shadcn/ui의 Form 컴포넌트를 활용하고 있는데, 그 컴포넌트에서 Context를 활용하여 값을 관리하고 있어서 ProfileForm 컴포넌트와 ContextProvider가 계속 리렌더링 되고 있다. 이것을 해결해 볼 방안도 찾아봐야겠다.
참고: https://heycoding.tistory.com/135