You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用react-hook-form和useContext实现多步骤表单值存储?求助排查

Hey there! Let's figure out why your multi-step form with react-hook-form and Context is acting up—sounds like the state sync between the two is the main culprit. Here's what's likely going wrong and how to fix it:

Key Issues & Solutions

1. Context isn't getting updated in real-time

Right now, it sounds like you're only pushing form values to Context when you hit SUBMIT, which is why you see an update then but no data stored before that. React-hook-form manages its own internal state, so you need to explicitly sync those changes to your Context as the user types.

  • Fix: Use react-hook-form's watch function to track value changes and update Context immediately:
    import { useForm, watch } from 'react-hook-form';
    import { useFormContext } from './your-form-context-file';
    
    function PersonalInfoStep() {
      const { register, control } = useForm();
      const { updateFormData } = useFormContext();
      const currentFormValues = watch(control); // Tracks all form field changes
    
      // Sync new values to Context whenever they change
      useEffect(() => {
        updateFormData(currentFormValues);
      }, [currentFormValues, updateFormData]);
    
      return (
        <div>
          <input {...register('firstName', { required: true })} placeholder="First Name" />
          <input {...register('lastName', { required: true })} placeholder="Last Name" />
        </div>
      );
    }
    

2. Context state is being overwritten instead of merged

If you're replacing the entire Context state object when updating, you'll lose data from previous steps. For example, if Step 1 saves name data and Step 2 saves contact info, overwriting the state would erase the name when you enter contact details.

  • Fix: Merge new values with existing Context state using the spread operator:
    import { createContext, useState, useContext } from 'react';
    
    const FormContext = createContext();
    
    export function FormProvider({ children }) {
      const [formData, setFormData] = useState({});
    
      const updateFormData = (newValues) => {
        // Spread existing state and merge new values
        setFormData(prevState => ({ ...prevState, ...newValues }));
      };
    
      return (
        <FormContext.Provider value={{ formData, updateFormData }}>
          {children}
        </FormContext.Provider>
      );
    }
    
    export const useFormContext = () => useContext(FormContext);
    

3. React-hook-form isn't initialized with Context data

When switching between steps, react-hook-form might reset its internal state unless you initialize it with the data already stored in Context. This can make it seem like Context has no data until you submit.

  • Fix: Pass defaultValues to useForm using your Context data:
    import { useForm } from 'react-hook-form';
    import { useFormContext } from './your-form-context-file';
    
    function ContactInfoStep() {
      const { formData } = useFormContext();
      const { register } = useForm({
        defaultValues: formData // Load existing Context data into the form
      });
    
      return (
        <div>
          <input {...register('email', { required: true, pattern: /^\S+@\S+$/i })} placeholder="Email" />
          <input {...register('phone', { required: true })} placeholder="Phone Number" />
        </div>
      );
    }
    

4. Invalid state on submit

If you're seeing values update but the form state is marked invalid when you submit, it's probably because you're not using react-hook-form's built-in submission handler correctly, or validation isn't applied to all fields across steps.

  • Fix: Use handleSubmit to manage submission, and ensure all fields have proper validation rules. For multi-step forms, you can also trigger validation for all fields on final submit:
    import { useForm, handleSubmit } from 'react-hook-form';
    import { useFormContext } from './your-form-context-file';
    
    function FinalSubmitStep() {
      const { formData } = useFormContext();
      const { register, handleSubmit, formState: { errors } } = useForm({
        defaultValues: formData
      });
    
      const onSubmit = (submittedData) => {
        // This should include all data from every step, synced via Context
        console.log('Full Submission Data:', submittedData);
        // Send to API or process here
      };
    
      return (
        <form onSubmit={handleSubmit(onSubmit)}>
          {/* Optional: Add a confirmation check */}
          <label>
            <input {...register('confirm', { required: 'Please confirm to submit' })} type="checkbox" />
            I confirm all details are correct
          </label>
          {errors.confirm && <p style={{ color: 'red' }}>{errors.confirm.message}</p>}
          <button type="submit">SUBMIT</button>
        </form>
      );
    }
    
Quick Troubleshooting Checks
  • Make sure every step component is wrapped inside your FormProvider—if not, they won't have access to the Context.
  • Double-check that all input fields have the register function applied—any field without it won't be tracked by react-hook-form.
  • Ensure your Context's updateFormData function isn't accidentally resetting the state (no setFormData({}) without spreading previous state!).

Since you mentioned the UI is rough but the core form behavior is otherwise on track, fixing these sync issues should get your Context populated correctly and resolve the invalid state on submit.

内容的提问来源于stack exchange,提问作者karo-s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 16:27:40