useFieldArray 사용하기

issol·2023년 4월 22일
0

Next

목록 보기
1/3

AS IS

서비스 특성 상 사용자에게 입력받는 form들이 많고, 같은 form을 여러개 중첩해서 받는 경우가 있다. 우리는 react-hook-form을 사용해서 여러 form들을 관리하고, validation을 하고 있는 상황이다. 하나의 폼, 즉 하나의 id를 가지는 중첩되지 않는 입력 칸들에 대해서는 validation과 입력 값들에 대한 제어가 쉬운데, 같은 입력 칸들인데 id만 달라지는 배열의 형태로 확장되면 관리가 너무 힘들었다.

이런 경우 여러 명을 추가할 때는 {성별, 나이, 이름, 집주소} 가 여러개 쌓이는

[{성별, 나이, 이름, 집주소}, {성별, 나이, 이름, 집주소}]

요런 구조가 되어야 한다. 그래서 이에 대한 관리를 편하게 하기 위한게 react-hook-form에서 제공하는 useFieldArray이다.

TO BE

여러 같은 객체를 배열형태로 관리되어야 하고 같은 validation을 적용받게 해야한다.

DONE

useFieldArray를 사용하는건 의외로 정말 간단하다.

import { useform, useFieldArray } from 'react-hook-form'

type UserInfoType = {
	pair : {
      sex : string
      age : number
      name : string
      address : string
    }[]
}

const { control, handleSubmit } = useForm<{UserInfoType}>({
	mode : onChange
    resolver: yupResolver(userInfoSchema),
})

 const {
    fields: pairFields,
    append,
    remove,
    update,
  } = useFieldArray({
    control,
    name: 'pair',
  })

UserInfoType에 pair라는 배열을 만들어주고 이 key값을 useFieldArray에 넣어주면 된다. 이제 어떻게 추가하고 삭제하는지 살펴보자.

const removePair = (item: { id: string }) => {
    const idx = pairFields.map(item => item.id).indexOf(item.id)
    idx !== -1 && remove(idx)
}

const addPair = () => {
	 append({ sex: '', age: null, name: '', address: '' })
}

삭제는 해당 item의 index를 넣어주면 되고, add는 빈 아이템들이 들어있는 객체를 추가해준다.
Controller에 해당 컴포넌트들을 넣어서 그려보자.

{pairFields?.map((item, idx) => {
	return (
    <div>
    	<FormControl>
        	<Controller 
            	name = {`pair.${idx}.sex`}
                control = {control}
                render = {({field : {onChange, value }}) => (
                	<AutoComplete 
                    	value={value}
                        options={sexOptions}
                        onChange={onChange}
                         renderOption={(props, option) => (
                              <Box component='li' {...props} key={props.id}>
                                {option.label}
                              </Box>
                            )}
                        renderInput={params =>(
                        	<TextField 
                            	{...params}
                                label="성별*"
                            />
                        )}
                    />
                )}
            />
        </FormControl>
        .... 나머지 동일... 
    </div>
    )
}


그럼 이렇게 id로 구분이 가능한 여러 객체가 같은 배열로 묶이게 되어 관리를 할 수 있게 된다!

profile
프론트 엔드 개발자

0개의 댓글