공통컴포넌트 만들기 field편

이대현·2024년 1월 8일
0

react

목록 보기
1/9

field 작업을할때 매번 따로 만들어주고 작업해주는게 귀찮아서 공통으로 어느정도의 커스텀이 가능하게 만들어서 사용하고있다.

폼작업을 할때 react-hook-form 라이브러리를 같이 사용하고있어서 해당 라이브러리를 활용해서 만들었다

컴포넌트 구성의 우선순위는

  1. 커스텀이 가능해야하는 것
  2. form의 control을 context로 전달받는 것
  3. 해당 field 지정이 편리해야 한다는 것이었다.
  4. 컴포넌트를 사용할때 한눈에 알아보기 좋아야하는것
import { Box, Typography, TextField, FormControl } from '@mui/material'
import { useController, useFormContext, Control } from 'react-hook-form'
import { TextFieldProps } from '@mui/material/TextField'

type Props = {
  name: string
  rules?: Object
  control?: Control<any>
} & TextFieldProps

const CommonTextField = (props: Props) => {
  const { name, rules, control: propsControl, ...rest } = props
  const { control } = useFormContext()

  const {
    field: { value, onChange },
    fieldState: { error },
  } = useController({
    control: propsControl ? propsControl : control,
    name: name,
    ...(rules && { rules }),
  })

  return (
    <FormControl fullWidth>
      <TextField
        value={value}
        onChange={onChange}
        size="small"
        {...rest}
        error={!!error?.message}
        helperText={error?.message ? error?.message : ''}
      />
    </FormControl>
  )
}

export default CommonTextField

FormProvider 안에서 필드들을 지정해서 사용하다보니
react-hook-form의 useFormContext라는 기능을 사용해서 부모로부터 props로 값을 전달받지 않고 context로 전달을 받아서 사용하는게 편리할거 같아서 해당기능을 사용했다.
추가로 useController로 해당 control이나 field name값을 컴포넌트 안에서 지정을 해줘서 해당 컴포넌트를 사용할때 name의 값을 props로 받아서 사용할 수 있게 설정해주었다.

실제 사용 예시:

  <FormProvider {...formMethods}>
  	 <CommonTextField name="name" rules={{ required: '이름을 입력해 주세요.' }} />
  </FormProvider>

useForm으로 받아온 formMethods들을 FormProvider태그에 넣어줌으로써 react-hook-form의 useFormContext()를 사용함으로써 FormProvider의 자식 컴포넌트 어디에서든 formMethods의 인자들을 접근할 수 있다.

실제로 이렇게 코드를 작성하니 form 관리를 편리하게 하고있다.

profile
Frontend Developer

0개의 댓글