react-hook-form多步骤表单返回上一步时输入框数据未回填问题
问题根因
你当前采用react-hook-form的非受控模式注册第三方UI输入框,切换步骤时对应步骤的组件会被条件渲染卸载,重新返回挂载时,register方法默认不会主动从全局表单状态中读取已有值初始化输入框,因此出现表单状态存储完整但输入框无填充的现象。
解决方案
方案1:使用Controller包裹输入框(最推荐)
Controller是react-hook-form专门用于适配受控组件、第三方UI组件的API,会自动同步全局表单状态与输入框的值,不受组件卸载挂载影响。
修改输入组件代码如下:
import { useFormContext, Controller } from 'react-hook-form'; import TextField from '@mui/material/TextField'; // 组件内部逻辑 const { control } = useFormContext(); <Controller name="email" control={control} render={({ field }) => <TextField label="Email" {...field} />} />
所有字段都按上述方式修改即可。
方案2:给register传入已有值作为默认值
如果不想大范围修改代码,可以在调用register时主动从全局表单状态读取当前值作为初始化默认值:
const { register, getValues } = useFormContext(); <TextField label="Email" {...register("email", { defaultValue: getValues("email") ?? "" })} />
方案3:改为显示/隐藏步骤组件,不卸载组件
修改父组件的渲染逻辑,所有步骤组件都保留在DOM中,仅通过样式控制显隐,避免组件卸载后重新挂载的初始化问题:
const CreateAccount = () => { const [currentStep, setCurrentStep] = useState(0); const methods = useForm<FormData>({ mode: "onChange" }); const onSubmit = (data) => console.log(data); const handleNextStep = () => currentStep < 5 && setCurrentStep(prev => prev + 1); const handlePreviousStep = () => currentStep > 0 && setCurrentStep(prev => prev - 1); const stepComponents = [ <UsernameEmail key={RegistrationSteps.UsernameEmail} handleNextStep={handleNextStep} handlePreviousStep={handlePreviousStep} />, <CreatePassword key={RegistrationSteps.Password} handleNextStep={handleNextStep} handlePreviousStep={handlePreviousStep} /> ]; return ( <Container maxWidth="sm"> <FormProvider {...methods}> <form onSubmit={methods.handleSubmit(onSubmit)}> {stepComponents.map((component, index) => ( <div key={index} style={{ display: index === currentStep ? 'block' : 'none' }}> {component} </div> ))} </form> </FormProvider> </Container> ); };
该方案性能更好,无需反复挂载卸载组件,适合步骤数量较少的场景。
内容的提问来源于stack exchange,提问作者Oleksandr Fomin
相关产品推荐
相关产品推荐

