如何用tRPC响应数据填充React useState初始值?
解决tRPC获取用户数据后同步到表单useState的问题
你的问题核心在于formData的初始值和用户实际数据脱节:虽然表单显示用了currentUser的数据,但formData本身始终保留初始的空字符串,导致修改单个字段时,未改动的字段仍为空,提交时覆盖数据库原有值。
解决方案
通过useEffect监听currentUser的异步返回结果,将用户数据同步到formData中,同时确保表单输入框绑定formData字段,保持显示和数据一致。
修改后的完整代码
import { useState, useEffect } from 'react'; import { useSession } from 'next-auth/react'; import { api } from '@/utils/trpc'; const UserProfileForm = () => { const { data: sessionData } = useSession(); const { data: currentUser } = api.user.get.useQuery( undefined, { enabled: sessionData?.user !== undefined } ); const [formData, setFormData] = useState({ firstname: "", lastname: "", }); const updateUser = api.user.update.useMutation(); // 监听currentUser变化,同步用户数据到formData useEffect(() => { if (currentUser?.user) { setFormData({ firstname: currentUser.user.firstname || "", lastname: currentUser.user.lastname || "" }); } }, [currentUser]); const handleInput = (e) => { const { name, value } = e.target; setFormData(prev => ({ ...prev, [name]: value })); }; // 提交处理示例 const handleSubmit = (e) => { e.preventDefault(); updateUser.mutate(formData); }; return ( <form onSubmit={handleSubmit}> <input name="firstname" value={formData.firstname} onChange={handleInput} placeholder="First Name" /> <input name="lastname" value={formData.lastname} onChange={handleInput} placeholder="Last Name" /> <button type="submit">Update Profile</button> </form> ); }; export default UserProfileForm;
关键说明
useEffect同步数据:
- 当
currentUser异步加载完成后,自动将用户的firstname和lastname同步到formData,确保初始值和用户实际数据一致。 - 依赖项
[currentUser]确保只有当用户数据变化时才触发更新,避免无效渲染。
- 当
表单绑定formData:
- 输入框的
value直接绑定formData字段,而不是currentUser,这样表单显示的内容始终和formData保持一致,避免显示与实际提交数据脱节的问题。
- 输入框的
避免空值覆盖:
- 同步数据时用
|| ""处理可能的空值,确保formData始终有合法的字符串值,不会出现undefined导致的表单异常。
- 同步数据时用
这样修改后,即使只修改单个字段,未改动的字段会保留用户原有数据,提交时就不会将数据库中的值覆盖为空了。
内容的提问来源于stack exchange,提问作者Fredy
相关产品推荐
相关产品推荐

