Creé un formulario en React usando MUI y React Hook Form. Estoy tratando de crear un elemento TextField personalizado que funcione como Seleccionar entrada . Me gustaría que fuera un componente no controlado con un Ref prop. Intenté pasar el accesorio inputRef como recomiendan los documentos MUI y React Hook Form, pero sin éxito.
<TextField id="id" name="name" select native="true" className={classes.textField} label="label" margin="normal" variant="outlined" inputRef={register({ required: "Choose one option" })} error={!!errors.name} > <MenuItem value="">Choose one option</MenuItem> <MenuItem value="3">03</MenuItem> <MenuItem value="6">06</MenuItem> <MenuItem value="9">09</MenuItem> <MenuItem value="12">12</MenuItem> <MenuItem value="16">16</MenuItem> <MenuItem value="18">18</MenuItem> </TextField> Una cosa que encontré es que si uso la select nativa con ref , funciona bien.
Además, traté de cambiar el accesorio inputRef a uno SelectProps pero tampoco funcionó.
El uso del componente Seleccionar de Material-ui con el formulario de gancho de reacción necesita que implemente una lógica personalizada con un controlador https://react-hook-form.com/api#Controller
Aquí hay un componente reutilizable que, con suerte, simplificará el código para usar ese componente Select en su aplicación:
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 as={ <Select labelId={labelId} label={label}> {children} </Select> } name={name} control={control} defaultValue={defaultValue} /> </FormControl> ); }; export default ReactHookFormSelect;Puedes usarlo en tu aplicación de esta manera:
<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>Aquí está su codeSandBox actualizado con este componente para las selecciones en el formulario de Información:
https://codesandbox.io/s/unit-multi-step-form-kgic4?file=/src/Register/Information.jsx:4406-5238
Aquí mi código que funciona, espero que pueda ayudar, necesito usar setValue
<TextField fullWidth inputRef={register({ name: 'name', })} select onChange={e => setValue('name', e.target.value, true)} label={label} defaultValue={defaultValue} > {options.map((option) => ( <MenuItem key={option.label} value={option.value}> {option.label} </MenuItem> ))} </TextField>Aquí usando selección nativa, no necesita setValue, pero valore siempre la cadena
<TextField fullWidth select SelectProps={{ native: true, inputProps: { ref: register, name: 'name' } }} label={label} defaultValue={defaultValue} > {options.map((option) => ( <option key={option.label} value={option.value}> {option.label} </option> ))} </TextField>✔ Me encontré con este mismo problema, y así es como resolví el mío:
<Select ... onChange={e => register({ name: 'academicLevel', value: e.target.value })}/>Este es un ejemplo que usa Material-UI con forma de gancho React. Debe agregar la validación en el accesorio 'inputRef' de TextField. También debe agregar la función 'onChange' para mantener el estado actualizado. 'shouldValidate' activará la validación.
<TextField select name='city' inputRef={register({ required: true })} onChange={e => setValue('city', e.target.value, { shouldValidate: true })} label="City" defaultValue=""> {cityList.map((option, index) => ( <MenuItem key={index} value={option}> {option} </MenuItem> ))} </TextField> {errors.city && <ErrorText>City is required</ErrorText>}Cuando usa la forma de gancho de reacción con la interfaz de usuario de material, no necesita usar onChange y setState. ¡Solo use inputRef y todo funciona!
Solo necesita pasar el registro a la Ref de entrada
<Select variant="outlined" name="reason" inputRef={register({ required: true })} >Actualización RHF v7
A continuación se muestra un ejemplo de código mínimo de MUI Select en formato RHF:
const { formState, getValues, watch, register, handleSubmit } = useForm(); const { errors } = formState; <TextField select fullWidth label="Select" defaultValue='' inputProps={register('currency', { required: 'Please enter currency', })} error={errors.currency} helperText={errors.currency?.message} > {currencies.map((option) => ( <MenuItem key={option.value} value={option.value}> {option.label} </MenuItem> ))} </TextField>