React Hook Form与其他组件结合使用:动态表单子组件数据未同步问题求助
Hey there! I see the issue with your DetailForm not syncing with the main react-hook-form setup. The problem is that your modal's text fields aren't connected to the form's state management—right now they're just standalone inputs that don't communicate with the main form's control object. Let's fix this step by step:
Step 1: Pass form control to DetailForm
First, you need to pass the control object from your main form into DetailForm—this is how react-hook-form links components to its state. Also, fix a small syntax error in your fields.map (you forgot curly braces around the JSX expression) and add a unique key to list items:
// Updated MainForm List section <List> {fields.map((item, index) => { return ( <ListItem key={item.id}> {/* Add unique key for list items */} <Controller name={`profiles.${index}.firstName`} control={control} render={({field}) => <TextField {...field} label="First Name" />} /> <Controller name={`profiles.${index}.lastName`} control={control} render={({field}) => <TextField {...field} label="Last Name" />} /> {/* Pass control prop to DetailForm */} <DetailForm index={index} control={control} /> </ListItem> ) })} </List>
Step 2: Connect modal inputs to react-hook-form
In DetailForm, use Controller (just like you did in the main form) to bind the email and phone fields to the main form's state. This ensures any input changes are synced back to the form's values:
// Updated DetailForm code import React from 'react'; import { Button, TextField, Dialog, DialogTitle, DialogContent, DialogActions, } from '@material-ui/core'; import { Controller } from 'react-hook-form'; // Import Controller export default function DetailForm(props: { index: number; control: any }) { const [dialogState, setDialogState] = React.useState<boolean>(false); const handleOpen = () => { setDialogState(true); }; const handleClose = () => { setDialogState(false); }; return ( <> <Button onClick={handleOpen} > Set Detail Profile </Button> <Dialog open={dialogState}> <DialogTitle>Detail Profile</DialogTitle> <DialogContent> <Controller name={`profiles.${props.index}.email`} control={props.control} render={({ field }) => ( <TextField {...field} label="Email Address" fullWidth margin="normal" /> )} /> <Controller name={`profiles.${props.index}.phone`} control={props.control} render={({ field }) => ( <TextField {...field} label="Phone Number" fullWidth margin="normal" /> )} /> </DialogContent> <DialogActions> <Button onClick={handleClose}> Cancel </Button> <Button onClick={handleClose}> Add </Button> </DialogActions> </Dialog> </> ) }
Step 3: Test the submission
Now when you enter values in the modal and submit the main form, the email and phone fields will be included in the data object logged from getValues().
Extra Tips
- The
useFieldArrayhook automatically adds a uniqueidto each field item, so usingkey={item.id}keeps your list items stable. - If you open the modal for an existing profile,
Controllerwill automatically pre-fill the inputs with the current form values. - You can add validation rules to the
Controllercomponents (e.g.,rules={{ required: "Email is required" }}) just like in the main form.
内容的提问来源于stack exchange,提问作者Pirikara

