본문 바로가기

[React-hook-form] controller-checkbox 반복문을 사용한 방식과 개별 작성 방식의 차이

@Jeeqong 2024. 10. 10. 15:00
반응형

 

react-hook-form 에서 control 을 안쓰겠다고 고집스럽게 힘들게 register 작업을 다해놓고 
커스덤 컴포넌트들을 만들다보니 짜즈응이 나서 결국 <Controller> 를 쓰는 방식으로 리팩토링 하는 중인데
왜죠..? 이해는 안가는데 그냥..그런갑다 해야지

 

1. 반복문을 사용한 코드 (예제에서 사용한 방식)

반복문을 사용하면 코드가 더 동적으로 변할 수 있으며, 여러 개의 체크박스를 간단하게 렌더링

const interestsCheckOptions = [
		{ id: 'sports', label: 'Sports', value: 'sports' },
		{ id: 'music', label: 'Music', value: 'music' },
		{ id: 'art', label: 'Art', value: 'art' },
		{ id: 'dance', label: 'Dance', value: 'dance' },
		{ id: 'movie', label: 'Movie', value: 'movie' },
	];

<ControllerWrapper
    name="email_preferences"
    control={control}
    defaultValue={[]}
    // rules={{ required: 'Please select an option' }}
    render={({ value = [], onChange }) => (
        <CheckboxGroup
            name="email_preferences"
            legendId="email_preferences"
            error={Array.isArray(errors.email_preferences) ? errors.email_preferences[0] : errors.email_preferences}
            className="my-[11px] gap-y-5"
            direction="vertical"
            // success={isSubmitted && !errors.interests}
        >
            <Checkbox
                name="email_preferences"
                id="accept_multiple_recipients"
                labelText="Accept to receive email sent to multiple recipients"
                value={EMAIL_PREFERENCES.ACCEPT_MULTIPLE_RECIPIENTS}
                checkedValues={value}
                onChange={(selectedValue) => {
                    if (value.includes(selectedValue)) {
                        onChange(value.filter((item: string) => item !== selectedValue));
                    } else {
                        onChange([...value, selectedValue]);
                    }
                    clearErrors('email_preferences');
                }}
            />
            <Checkbox
                name="email_preferences"
                id="send_copy_to_personal_email"
                labelText="Send copy to personal email"
                value={EMAIL_PREFERENCES.SEND_COPY_TO_PERSONAL_EMAIL}
                checkedValues={value}
                onChange={(selectedValue) => {
                    if (value.includes(selectedValue)) {
                        onChange(value.filter((item: string) => item !== selectedValue));
                    } else {
                        onChange([...value, selectedValue]);
                    }
                    clearErrors('email_preferences');
                }}
            />
        </CheckboxGroup>
    )}
/>

 

이 방식의 장점:

  • 반복문을 사용해 여러 체크박스를 간결하게 렌더링할 수 있습니다.
  • 같은 로직을 여러 번 중복 작성할 필요가 없습니다.

2. 개별적으로 작성한 방식

반복문을 사용하지 않고 각각의 체크박스를 개별로 처리한 방식

<ControllerWrapper
    name="email_preferences"
    control={control}
    defaultValue={[]}
    render={({ value = [], onChange }) => (
        <CheckboxGroup
            name="email_preferences"
            legendId="email_preferences"
            error={Array.isArray(errors.email_preferences) ? errors.email_preferences[0] : errors.email_preferences}
            className="my-[11px] gap-y-5"
            direction="vertical"
        >
            <Checkbox
                name="email_preferences"
                id="accept_multiple_recipients"
                labelText="Accept to receive email sent to multiple recipients"
                value={EMAIL_PREFERENCES.ACCEPT_MULTIPLE_RECIPIENTS}
                checkedValues={value}
                onChange={(selectedValue) => {
                    if (value.includes(selectedValue)) {
                        onChange(value.filter((item: string) => item !== selectedValue));
                    } else {
                        onChange([...value, selectedValue]);
                    }
                    clearErrors('email_preferences');
                }}
            />
            <Checkbox
                name="email_preferences"
                id="send_copy_to_personal_email"
                labelText="Send copy to personal email"
                value={EMAIL_PREFERENCES.SEND_COPY_TO_PERSONAL_EMAIL}
                checkedValues={value}
                onChange={(selectedValue) => {
                    if (value.includes(selectedValue)) {
                        onChange(value.filter((item: string) => item !== selectedValue));
                    } else {
                        onChange([...value, selectedValue]);
                    }
                    clearErrors('email_preferences');
                }}
            />
        </CheckboxGroup>
    )}
/>

 

이 방식의 장점:

  • 각 체크박스를 개별적으로 다루므로, 각각의 체크박스에 대해 더 세부적인 컨트롤을 할 수 있다.

 

차이점

  • 동적 렌더링: 반복문을 사용한 방식은 체크박스가 여러 개일 때 동적으로 쉽게 처리할 수 있습니다. 데이터가 변할 때 자동으로 렌더링되고 관리된다.
  • 개별 처리: 개별로 작성한 방식은 각 체크박스에 대해 직접 컨트롤이 가능하고, 중간에 다른 요소나 논리를 추가하기 용이하다.

왜 다른 결과가 나올까?

  • 상태 관리: 두 방식 모두 value라는 배열을 관리하지만, 체크박스가 여러 개일 경우 상태 관리가 적절하지 않으면 값이 정상적으로 업데이트되지 않을 수 있다. 특히 onChange 함수가 value 배열을 제대로 업데이트하지 않으면 문제가 발생할 수 있다.
  • 타이밍 문제: 반복문에서 map을 사용할 경우, 렌더링 타이밍 문제나 상태 업데이트 타이밍 문제로 인해 체크박스의 상태가 의도대로 작동하지 않을 수 있다. 예를 들어, value.includes(selectedValue) 로직이 실행되기 전에 value가 최신 상태로 반영되지 않는 경우도 있다.

결론

두 방식 모두 동일하게 작동해야 하지만, 렌더링 타이밍이나 상태 관리 방식에서 차이가 생길 수 있다. 체크박스를 여러 개 렌더링하는 상황에서는 반복문을 사용하는 것이 더 유연하고 유지보수가 쉽다.

 
반응형
Jeeqong
@Jeeqong :: JQVAULT

Jeeqong's vault : 정보/기록을 쌓아두는 공간 웹개발 포스팅 일상 리뷰를 기록하는 공간입니다.

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차