개발관련/리액트

React-hook-form과 Material UI MUI Select Component 같이 사용 하는 방법

개발자 Dane 2022. 11. 3. 21:17
반응형

React-hook-form과 Material UI MUI Select Component 같이 사용 하는 방법

react-hook-form과 MUI(Material-UI)의 Select 컴포넌트 같이 사용하려고 하는 경우에는 react-hook-form과 MUI가 모두 ref를 통해서 dom을 제어하기 때문에 라이브러리들끼리 충돌해서 제대로 동작하지 않습니다.

 

이 경우 react-hook-form의 Controller API를 사용해주면 됩니다.

 

react-hook-form 버젼 7 기준

 

Controller 컴포넌트 사용

import FormControl from "@material-ui/core/FormControl";
import InputLabel from "@material-ui/core/InputLabel";
import Select from "@material-ui/core/Select";
import { Controller } from "react-hook-form";

const ReactHookFormSelect = ({
  name,
  label,
  control,
  defaultValue,
  children,
  ...props
}) => {
  const labelId = `${name}-label`;
  return (
    <FormControl {...props}>
      <InputLabel id={labelId}>{label}</InputLabel>
        <Controller
          render={({
            field: { onChange, onBlur, value, name, ref },
            fieldState: { invalid, isTouched, isDirty, error },
          }) => (
            <Selecct
              value={value}
              onChange={onChange}
              onBlur={onBlur}
              inputRef={ref}
            >
            {children}
            </Select>
	  )}
      name="TextField"
      control={control}
      rules={{ required: true }}
    	/>
    </FormControl>
  );
};
export default ReactHookFormSelect;

위 처럼 Controller로 감싼 컴포넌트를 만들면 손쉽게 재사용이 가능 합니다.

<ReactHookFormSelect
  id="numero_prestacao"
  name="numero_prestacao"
  className={classes.textField}
  label="Em quantas parcelas?"
  control={control}
  defaultValue={numero_prestacao || ""}
  variant="outlined"
  margin="normal"
>
  <MenuItem value="">Escolha uma opção</MenuItem>
  <MenuItem value="3">03 parcelas</MenuItem>
  <MenuItem value="6">06 parcelas</MenuItem>
  <MenuItem value="9">09 parcelas</MenuItem>
  <MenuItem value="12">12 parcelas</MenuItem>
  <MenuItem value="16">16 parcelas</MenuItem>
  <MenuItem value="18">18 parcelas</MenuItem>
</ReactHookFormSelect>

사용시에는 일반적인 Select Component 처럼 사용할수 있습니다.

 

useController 사용 

useController를 사용하는 방법이 더 직관적일수 있습니다.

 

import { Select } from '@material-ui/core'
import { MenuItem } from '@mui/material'
import { useController, useForm } from 'react-hook-form'

function Select({ control, name }) {
	const {
		field: { onChange, onBlur, name, value, ref },
		fieldState: { invalid, isTouched, isDirty },
		formState: { touchedFields, dirtyFields },
	} = useController({
		name,
		control,
		rules: { required: true },
		defaultValue: '',
	})

	return (
		<Select
			onChange={onChange} // send value to hook form
			onBlur={onBlur} // notify when input is touched/blur
			value={value} // input value
			name={name} // send down the input name
			inputRef={ref} // send input ref, so we can focus on input when error appear
		>
			<MenuItem value="01"> 01</MenuItem>
			<MenuItem value="02"> 02</MenuItem>
			<MenuItem value="03"> 03</MenuItem>
			<MenuItem value="04"> 04</MenuItem>
		</Select>
	)
}

 

감사합니다.

 

 

 

참고 

https://react-hook-form.com/api/usecontroller/controller

 

Controller

Performant, flexible and extensible forms with easy-to-use validation.

react-hook-form.com

https://mui.com/material-ui/react-select/

 

React Select component - Material UI

Select components are used for collecting user provided information from a list of options.

mui.com

 

반응형