field 작업을할때 매번 따로 만들어주고 작업해주는게 귀찮아서 공통으로 어느정도의 커스텀이 가능하게 만들어서 사용하고있다.
폼작업을 할때 react-hook-form 라이브러리를 같이 사용하고있어서 해당 라이브러리를 활용해서 만들었다
컴포넌트 구성의 우선순위는
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 관리를 편리하게 하고있다.