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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 16:43:28