Next.js刷新页面后如何根据用户会话更新表单默认值?
问题描述
使用shadcn表单结合Next-Auth实现社交登录后的用户资料表单,登录跳转至资料页时,姓名、邮箱能通过useForm的defaultValues预填,但手动刷新页面后,表单无法自动填充正确的用户信息。原因是useSession获取会话存在约0.5秒的延迟,useForm初始化时会话还未加载完成,导致默认值为空。
解决方案
核心思路是在会话加载完成后,调用useForm提供的reset方法重新设置表单值,同时处理会话加载状态避免报错:
- 根据
status判断会话状态,加载中时显示加载提示,避免访问未初始化的session.user - 用
useEffect监听session和status的变化,当会话验证通过(status === 'authenticated')时,调用form.reset()更新表单字段值
修改后的Profile页面代码
'use client' // 导入必要依赖 import { z } from 'zod'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { useSession } from 'next-auth/react'; import { Form, FormControl, FormField, FormItem, FormLabel } from '@/components/ui/form'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; const formSchema = z.object({ firstName: z.string().min(2), lastName: z.string(), emailAddress: z.string().email(), }); const Profile = () => { const { data: session, status } = useSession(); const form = useForm({ resolver: zodResolver(formSchema), defaultValues: { firstName: "", lastName: "", emailAddress: "", } }); // 会话加载完成后重置表单值 useEffect(() => { if (status === 'authenticated' && session?.user) { form.reset({ firstName: session.user.name || "", emailAddress: session.user.email || "", lastName: "" }); } }, [session, status, form]); // 表单提交处理 const onSubmit = (data) => { console.log('提交的表单数据:', data); // 这里添加更新用户资料的逻辑 }; const createFormField_Input = (inputParamVar, inputParamName, inputPlaceholder) => { return ( <FormField control={form.control} name={inputParamVar} render={({ field }) => { return ( <FormItem> <FormLabel>{inputParamName}</FormLabel> <FormControl> <Input placeholder={inputPlaceholder} {...field} /> </FormControl> </FormItem> ) }} /> ); } // 会话加载中显示提示 if (status === 'loading') { return <div>加载中...</div>; } return ( <Form {...form} > <form onSubmit={form.handleSubmit(onSubmit)} className='flex flex-col gap-5'> {createFormField_Input("firstName", "First Name", 'First Name')} {createFormField_Input("lastName", "Last Name", 'Last Name')} {createFormField_Input("emailAddress", "Email Address", 'Email Address')} <Button type="submit">Submit</Button> </form> </Form> ); }; export default Profile;
关键说明
- 加载状态处理:当
status为loading时返回加载提示,避免会话未加载完成时访问session.user导致报错 - 会话变化监听:一旦会话验证通过,立即调用
form.reset()将用户信息同步到表单,无论首次登录跳转还是页面刷新,都能确保表单值正确填充 - 初始默认值设空:因初始会话未加载,设置空值更合理,后续通过
reset覆盖初始值
内容的提问来源于stack exchange,提问作者Jkiahb
相关产品推荐
相关产品推荐

