如何将 MUI Select 与 react-hook-form 一起使用?
How to use MUI Select with react-hook-form?
我使用 MUI 和 React Hook Form 在 React 中构建了一个表单。我正在尝试创建一个自定义 TextField
元素作为 Select Input。我希望它是一个不受控制的组件,带有 Ref 道具。我尝试按照 MUI 和 React Hook Form 文档的建议传递 inputRef
道具,但没有成功。
<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>
我发现的一件事是,如果我使用原生 select
和 ref
,效果很好
此外,我尝试将 inputRef
属性更改为 SelectProps
,但没有成功'我也不工作。
将 Material-ui 中的 Select 组件与反应钩子形式一起使用需要您使用控制器实现自定义逻辑 https://react-hook-form.com/api#Controller
这是一个可重复使用的组件,有望简化代码以在您的应用中使用该 Select 组件:
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;
您可以像这样在您的应用中使用它:
<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>
这是使用此组件更新的 codeSandBox,用于信息表单中的选择:
https://codesandbox.io/s/unit-multi-step-form-kgic4?file=/src/Register/Information.jsx:4406-5238
这是我的有效代码,希望对您有所帮助,需要使用 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>
这里使用原生select,不需要setValue,但value总是string
<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>
✔ 我遇到了同样的问题,这就是我解决问题的方法:
<Select ... onChange={e => register({ name: 'academicLevel', value: e.target.value })}/>
这是一个使用 Material-UI 和 React 挂钩形式的示例。您需要在 TextField 的 'inputRef' 属性中添加验证。您还需要添加 'onChange' 函数来保持状态更新。 'shouldValidate' 将触发验证。
<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>}
当您将 react-hook-form 与 material UI 一起使用时,您不需要使用 onChange 和 setState。仅使用 inputRef 一切正常!
只需要将寄存器传递给Input Ref
<Select
variant="outlined"
name="reason"
inputRef={register({ required: true })}
>
RHF v7 更新
下面是 RHF 形式的 MUI Select
的最小代码示例:
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>
我使用 MUI 和 React Hook Form 在 React 中构建了一个表单。我正在尝试创建一个自定义 TextField
元素作为 Select Input。我希望它是一个不受控制的组件,带有 Ref 道具。我尝试按照 MUI 和 React Hook Form 文档的建议传递 inputRef
道具,但没有成功。
<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>
我发现的一件事是,如果我使用原生 select
和 ref
,效果很好
此外,我尝试将 inputRef
属性更改为 SelectProps
,但没有成功'我也不工作。
将 Material-ui 中的 Select 组件与反应钩子形式一起使用需要您使用控制器实现自定义逻辑 https://react-hook-form.com/api#Controller
这是一个可重复使用的组件,有望简化代码以在您的应用中使用该 Select 组件:
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;
您可以像这样在您的应用中使用它:
<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>
这是使用此组件更新的 codeSandBox,用于信息表单中的选择:
https://codesandbox.io/s/unit-multi-step-form-kgic4?file=/src/Register/Information.jsx:4406-5238
这是我的有效代码,希望对您有所帮助,需要使用 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>
这里使用原生select,不需要setValue,但value总是string
<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>
✔ 我遇到了同样的问题,这就是我解决问题的方法:
<Select ... onChange={e => register({ name: 'academicLevel', value: e.target.value })}/>
这是一个使用 Material-UI 和 React 挂钩形式的示例。您需要在 TextField 的 'inputRef' 属性中添加验证。您还需要添加 'onChange' 函数来保持状态更新。 'shouldValidate' 将触发验证。
<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>}
当您将 react-hook-form 与 material UI 一起使用时,您不需要使用 onChange 和 setState。仅使用 inputRef 一切正常!
只需要将寄存器传递给Input Ref
<Select
variant="outlined"
name="reason"
inputRef={register({ required: true })}
>
RHF v7 更新
下面是 RHF 形式的 MUI Select
的最小代码示例:
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>