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

Next.js(v14)中react-hook-form多页表单数据跨路由保留求助

多页表单数据持久化解决方案

问题核心是你的FormProvider在路由切换时会重新初始化useForm,且未保留用户已输入的数据,以下是两种可行的解决方法:

方法一:组件内state持久化(仅内存保留,刷新丢失)

修改FormProvider,将表单数据存在组件state中,作为useForm的动态默认值,同时监听表单变化同步更新state:

// FormProvider.tsx
import { useState, useEffect } from 'react';
import { useForm, FormProvider as RHFormProvider, Form } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import MyFormSchema from './your-schema-path'; // 替换为你的Schema路径

type MyForm = {
  name: string;
  description: string;
};

export const FormProvider = ({ children }: { children: React.ReactNode }) => {
  // 初始化state,默认值为初始空数据
  const [formData, setFormData] = useState<MyForm>({
    name: '',
    description: ''
  });

  const form = useForm<MyForm>({
    defaultValues: formData, // 动态绑定state作为默认值
    resolver: zodResolver(MyFormSchema),
  });

  // 监听表单值变化,实时更新state
  useEffect(() => {
    const unsubscribe = form.watch((values) => {
      setFormData(values);
    });
    return unsubscribe;
  }, [form]);

  const onSubmit = (data: MyForm) => {
    console.log('提交数据:', data);
    // 提交后可根据需求重置state或执行其他逻辑
  };

  return (
    <RHFormProvider {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)}>
        {children}
      </form>
    </RHFormProvider>
  );
};

路由切换时,FormProvider的state会保留之前的输入数据,useForm初始化时会复用该数据,避免重置。

方法二:localStorage持久化(刷新页面也保留)

如果需要刷新页面后仍保留数据,可结合localStorage实现持久化:

// FormProvider.tsx
import { useEffect } from 'react';
import { useForm, FormProvider as RHFormProvider, Form } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import MyFormSchema from './your-schema-path';

type MyForm = {
  name: string;
  description: string;
};

const STORAGE_KEY = 'multi-step-form-data';

export const FormProvider = ({ children }: { children: React.ReactNode }) => {
  // 从localStorage读取已有数据,无数据则用默认值
  const getDefaultValues = (): MyForm => {
    const saved = localStorage.getItem(STORAGE_KEY);
    return saved ? JSON.parse(saved) : { name: '', description: '' };
  };

  const form = useForm<MyForm>({
    defaultValues: getDefaultValues(),
    resolver: zodResolver(MyFormSchema),
  });

  // 监听表单变化,实时保存到localStorage
  useEffect(() => {
    const unsubscribe = form.watch((values) => {
      localStorage.setItem(STORAGE_KEY, JSON.stringify(values));
    });
    return unsubscribe;
  }, [form]);

  const onSubmit = (data: MyForm) => {
    console.log('提交数据:', data);
    // 提交完成后可清除localStorage中的缓存
    localStorage.removeItem(STORAGE_KEY);
  };

  return (
    <RHFormProvider {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)}>
        {children}
      </form>
    </RHFormProvider>
  );
};

注意:若表单包含敏感数据,建议改用sessionStorage或方法一的内存state,避免数据泄露。

另外,如果你使用Next.js 14的App Router,需将FormProvider放在layout.tsx中(Pages Router则保持_app.tsx的写法即可),确保路由切换时FormProvider不会被卸载。

内容的提问来源于stack exchange,提问作者kayu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 04:53:10