React Hook Form 注册相同字段名的不同表单
React Hook Form Register Different Forms With Same Field Names
我有一个 material ui 步进器,其中有多种形式使用 react-hook-form
。当我在步骤之间切换时,我希望有一个新的 useForm
挂钩来创建新的 register
函数来注册新的表单字段,但是当我在步骤之间切换时,第二个表单具有第一个表单的数据。我至少看到一个问题,有人试图在同一组件的同一页面上创建两个表单,但在这种情况下,我试图在不同的步骤中使用组件的不同实例创建两个独特的表单。似乎 react-hook-form
没有更新 useForm
挂钩,或者正在回收添加到第一个 register
调用的表单字段。
为什么 react-hook-form
不使用新的 register
函数将表单字段注册到新的 useForm
挂钩?或者至少,为什么不在步骤之间创建新的 useForm
挂钩?
DynamicForm
组件。这些组件中有两个(步进器中的每个步骤一个)。
import { Button, Grid } from "@material-ui/core";
import React from "react";
import { useForm } from "react-hook-form";
import { buttonStyles } from "../../../styles/buttonStyles";
import AppCard from "../../shared/AppCard";
import { componentsMap } from "../../shared/form";
export const DynamicForm = (props) => {
const buttonClasses = buttonStyles();
const { defaultValues = {} } = props;
const { handleSubmit, register } = useForm({ defaultValues });
const onSubmit = (userData) => {
props.handleSubmit(userData);
};
return (
<form
id={props.formName}
name={props.formName}
onSubmit={handleSubmit((data) => onSubmit(data))}
>
<AppCard
headline={props.headline}
actionButton={
props.actionButtonText && (
<Button className={buttonClasses.outlined} type="submit">
{props.actionButtonText}
</Button>
)
}
>
<Grid container spacing={2}>
{props.formFields.map((config) => {
const FormComponent = componentsMap.get(config.component);
return (
<Grid key={`form-field-${config.config.name}`} item xs={12}>
<FormComponent {...config.config} register={register} />
</Grid>
);
})}
</Grid>
</AppCard>
</form>
);
};
N.B。图像是相同的,因为表单将包含相同的信息,即名称相同的表单字段。
第一种形式的条目:
第二种形式的条目:
每个表单都是使用这样的配置创建的:
{
component: DynamicForm,
label: "Stepper Label",
config: {
headline: "Form 1",
actionButtonText: "Next",
formName: 'form-name',
defaultValues: defaultConfigObject,
formFields: [
{
component: "AppTextInput",
config: {
label: "Field 1",
name: "field_1",
},
},
{
component: "AppTextInput",
config: {
label: "Field2",
name: "field_2",
},
},
{
component: "AppTextInput",
config: {
label: "Field3",
name: "field_3",
},
},
{
component: "AppTextInput",
config: {
label: "Field4",
name: "field4",
},
},
],
handleSubmit: (formData) => console.log(formData),
},
},
步骤中的活动组件处理如下:
import { Button, createStyles, makeStyles, Theme } from "@material-ui/core";
import React, { useContext, useEffect, useState } from "react";
import { StepperContext } from "./StepperProvider";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
buttonsContainer: {
margin: theme.spacing(2),
},
buttons: {
display: "flex",
justifyContent: "space-between",
},
})
);
export const StepPanel = (props) => {
const { activeStep, steps, handleBack, handleNext, isFinalStep } = useContext(
StepperContext
);
const [activeComponent, setActiveComponent] = useState(steps[activeStep]);
const classes = useStyles();
useEffect(() => {
setActiveComponent(steps[activeStep]);
}, [activeStep]);
return (
<div>
<activeComponent.component {...activeComponent.config} />
{
isFinalStep ? (
<div className={classes.buttonsContainer}>
<div className={classes.buttons}>
<Button disabled={activeStep === 0} onClick={handleBack}>
Back
</Button>
<Button
variant="contained"
color="primary"
onClick={props.finishFunction}
>
Finish And Submit
</Button>
</div>
</div>
)
:
null
}
</div>
);
};
从你的图片来看,每个表格看起来都一样。您应该尝试为您的组件提供一个唯一的 key
值,以便 React 知道每个表单都是不同的。在这种情况下,它可以是步骤编号,例如:
<activeComponent.component {...props} key='form-step-1'>
我有一个 material ui 步进器,其中有多种形式使用 react-hook-form
。当我在步骤之间切换时,我希望有一个新的 useForm
挂钩来创建新的 register
函数来注册新的表单字段,但是当我在步骤之间切换时,第二个表单具有第一个表单的数据。我至少看到一个问题,有人试图在同一组件的同一页面上创建两个表单,但在这种情况下,我试图在不同的步骤中使用组件的不同实例创建两个独特的表单。似乎 react-hook-form
没有更新 useForm
挂钩,或者正在回收添加到第一个 register
调用的表单字段。
为什么 react-hook-form
不使用新的 register
函数将表单字段注册到新的 useForm
挂钩?或者至少,为什么不在步骤之间创建新的 useForm
挂钩?
DynamicForm
组件。这些组件中有两个(步进器中的每个步骤一个)。
import { Button, Grid } from "@material-ui/core";
import React from "react";
import { useForm } from "react-hook-form";
import { buttonStyles } from "../../../styles/buttonStyles";
import AppCard from "../../shared/AppCard";
import { componentsMap } from "../../shared/form";
export const DynamicForm = (props) => {
const buttonClasses = buttonStyles();
const { defaultValues = {} } = props;
const { handleSubmit, register } = useForm({ defaultValues });
const onSubmit = (userData) => {
props.handleSubmit(userData);
};
return (
<form
id={props.formName}
name={props.formName}
onSubmit={handleSubmit((data) => onSubmit(data))}
>
<AppCard
headline={props.headline}
actionButton={
props.actionButtonText && (
<Button className={buttonClasses.outlined} type="submit">
{props.actionButtonText}
</Button>
)
}
>
<Grid container spacing={2}>
{props.formFields.map((config) => {
const FormComponent = componentsMap.get(config.component);
return (
<Grid key={`form-field-${config.config.name}`} item xs={12}>
<FormComponent {...config.config} register={register} />
</Grid>
);
})}
</Grid>
</AppCard>
</form>
);
};
N.B。图像是相同的,因为表单将包含相同的信息,即名称相同的表单字段。
第一种形式的条目:
第二种形式的条目:
每个表单都是使用这样的配置创建的:
{
component: DynamicForm,
label: "Stepper Label",
config: {
headline: "Form 1",
actionButtonText: "Next",
formName: 'form-name',
defaultValues: defaultConfigObject,
formFields: [
{
component: "AppTextInput",
config: {
label: "Field 1",
name: "field_1",
},
},
{
component: "AppTextInput",
config: {
label: "Field2",
name: "field_2",
},
},
{
component: "AppTextInput",
config: {
label: "Field3",
name: "field_3",
},
},
{
component: "AppTextInput",
config: {
label: "Field4",
name: "field4",
},
},
],
handleSubmit: (formData) => console.log(formData),
},
},
步骤中的活动组件处理如下:
import { Button, createStyles, makeStyles, Theme } from "@material-ui/core";
import React, { useContext, useEffect, useState } from "react";
import { StepperContext } from "./StepperProvider";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
buttonsContainer: {
margin: theme.spacing(2),
},
buttons: {
display: "flex",
justifyContent: "space-between",
},
})
);
export const StepPanel = (props) => {
const { activeStep, steps, handleBack, handleNext, isFinalStep } = useContext(
StepperContext
);
const [activeComponent, setActiveComponent] = useState(steps[activeStep]);
const classes = useStyles();
useEffect(() => {
setActiveComponent(steps[activeStep]);
}, [activeStep]);
return (
<div>
<activeComponent.component {...activeComponent.config} />
{
isFinalStep ? (
<div className={classes.buttonsContainer}>
<div className={classes.buttons}>
<Button disabled={activeStep === 0} onClick={handleBack}>
Back
</Button>
<Button
variant="contained"
color="primary"
onClick={props.finishFunction}
>
Finish And Submit
</Button>
</div>
</div>
)
:
null
}
</div>
);
};
从你的图片来看,每个表格看起来都一样。您应该尝试为您的组件提供一个唯一的 key
值,以便 React 知道每个表单都是不同的。在这种情况下,它可以是步骤编号,例如:
<activeComponent.component {...props} key='form-step-1'>