如何将 useForm 的寄存器与动态参数一起使用?
How can I use useForm's register with dynamic parameter?
我想使用 react-hook-form 创建一个表单,但我遇到了问题。正如我发现的那样,v7 中有一个很大的变化,所以我用作参考的代码不起作用。我尝试修改它,发现问题出在注册上,但我无法动态传递该名称参数。
我的主要组成部分。
import React from 'react';
import i18next from 'i18next';
import { Button, Grid, Typography } from '@material-ui/core';
import { useForm, FormProvider } from 'react-hook-form';
import { Link } from 'react-router-dom';
import FormInput from './CustomTextField'
const AddressForm = ({ next }) => {
const methods = useForm();
return (
<>
<Typography variant="h6" gutterBottom>
{i18next.t('shipping_address')}
</Typography>
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit((data) => {
console.log(data);
next({ ...data })})}>
<Grid container spacing={3}>
<FormInput required register={methods.register} name='lastName' label={i18next.t('last_name')} />
<FormInput required register={methods.register} name='firstName' label={i18next.t('first_name')} />
<FormInput required register={methods.register} name='email' label={i18next.t('mail')} />
<FormInput required register={methods.register} name='zip' label={i18next.t('zip_code')} />
<FormInput required register={methods.register} name='city' label={i18next.t('city')} />
<FormInput required register={methods.register} name='address1' label={i18next.t('address_1')} />
</Grid>
<br />
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Button component={Link} to="/cart" variant="outlined">
{i18next.t('back_to_cart')}
</Button>
<Button type="submit" variant="contained" color="primary">
{i18next.t('next_step')}
</Button>
</div>
</form>
</FormProvider>
</>
)
}
export default AddressForm
CustomTextField 组件:
import React from 'react';
import { TextField, Grid } from '@material-ui/core';
import { useFormContext, Controller } from 'react-hook-form';
const CustomTextField = ({ name, label, register, required}) => {
const { control } = useFormContext();
return (
<Grid item xs={12} sm={6}>
<Controller
control={control}
name={name}
render = {(field) => (
<TextField
{...register({name})} // <--- It is not working like this
label={label}
required={required}
/>
)}
/>
</Grid>
)
}
export default CustomTextField
根据文档:https://react-hook-form.com/api/useform/register
它将输入字段的名称作为参数,如果我将它作为字符串传入,它就可以正常工作。如何将 name
的值作为参数传递给 register()
函数?
问题是您混合了 RHF 的 <Controller />
和 register
。由于 Mui 的 <TextField />
是一个外部控制组件,您应该使用 <Controller />
。查看文档 here 了解更多信息。
const CustomTextField = ({ name, label, register, required}) => {
const { control } = useFormContext();
return (
<Grid item xs={12} sm={6}>
<Controller
control={control}
name={name}
render={({ field: { ref, ...field } }) => (
<TextField
{...field}
inputRef={ref}
label={label}
required={required}
/>
)}
/>
</Grid>
)
}
如果你真的想在这里使用 register
,你必须删除包装 <Controller />
并将 name
作为字符串传递,而不是像你现在正在做的那样作为对象传递.但我建议使用 <Controller />
与 register
一样,您将失去为 <TextField />
输入元素设置正确 ref
的功能,因为它是通过 inputRef
prop 而不是使用 RHF register
使用的 ref
。
const CustomTextField = ({ name, label, register, required}) => {
const { control } = useFormContext();
return (
<Grid item xs={12} sm={6}>
<TextField
{...register(name)}
label={label}
required={required}
/>
</Grid>
)
}
我想使用 react-hook-form 创建一个表单,但我遇到了问题。正如我发现的那样,v7 中有一个很大的变化,所以我用作参考的代码不起作用。我尝试修改它,发现问题出在注册上,但我无法动态传递该名称参数。
我的主要组成部分。
import React from 'react';
import i18next from 'i18next';
import { Button, Grid, Typography } from '@material-ui/core';
import { useForm, FormProvider } from 'react-hook-form';
import { Link } from 'react-router-dom';
import FormInput from './CustomTextField'
const AddressForm = ({ next }) => {
const methods = useForm();
return (
<>
<Typography variant="h6" gutterBottom>
{i18next.t('shipping_address')}
</Typography>
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit((data) => {
console.log(data);
next({ ...data })})}>
<Grid container spacing={3}>
<FormInput required register={methods.register} name='lastName' label={i18next.t('last_name')} />
<FormInput required register={methods.register} name='firstName' label={i18next.t('first_name')} />
<FormInput required register={methods.register} name='email' label={i18next.t('mail')} />
<FormInput required register={methods.register} name='zip' label={i18next.t('zip_code')} />
<FormInput required register={methods.register} name='city' label={i18next.t('city')} />
<FormInput required register={methods.register} name='address1' label={i18next.t('address_1')} />
</Grid>
<br />
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Button component={Link} to="/cart" variant="outlined">
{i18next.t('back_to_cart')}
</Button>
<Button type="submit" variant="contained" color="primary">
{i18next.t('next_step')}
</Button>
</div>
</form>
</FormProvider>
</>
)
}
export default AddressForm
CustomTextField 组件:
import React from 'react';
import { TextField, Grid } from '@material-ui/core';
import { useFormContext, Controller } from 'react-hook-form';
const CustomTextField = ({ name, label, register, required}) => {
const { control } = useFormContext();
return (
<Grid item xs={12} sm={6}>
<Controller
control={control}
name={name}
render = {(field) => (
<TextField
{...register({name})} // <--- It is not working like this
label={label}
required={required}
/>
)}
/>
</Grid>
)
}
export default CustomTextField
根据文档:https://react-hook-form.com/api/useform/register
它将输入字段的名称作为参数,如果我将它作为字符串传入,它就可以正常工作。如何将 name
的值作为参数传递给 register()
函数?
问题是您混合了 RHF 的 <Controller />
和 register
。由于 Mui 的 <TextField />
是一个外部控制组件,您应该使用 <Controller />
。查看文档 here 了解更多信息。
const CustomTextField = ({ name, label, register, required}) => {
const { control } = useFormContext();
return (
<Grid item xs={12} sm={6}>
<Controller
control={control}
name={name}
render={({ field: { ref, ...field } }) => (
<TextField
{...field}
inputRef={ref}
label={label}
required={required}
/>
)}
/>
</Grid>
)
}
如果你真的想在这里使用 register
,你必须删除包装 <Controller />
并将 name
作为字符串传递,而不是像你现在正在做的那样作为对象传递.但我建议使用 <Controller />
与 register
一样,您将失去为 <TextField />
输入元素设置正确 ref
的功能,因为它是通过 inputRef
prop 而不是使用 RHF register
使用的 ref
。
const CustomTextField = ({ name, label, register, required}) => {
const { control } = useFormContext();
return (
<Grid item xs={12} sm={6}>
<TextField
{...register(name)}
label={label}
required={required}
/>
</Grid>
)
}