我对 Next.js 14 的应用程序路由器、Supabase Auth 和 Supabase 数据库非常陌生。这是我第一个使用这三个项目的项目。我当前的目标是让用户创建一个帐户,使用魔术链接登录,填写个人资料表格,其中他们的电子邮件地址不可编辑且已预先填充,并且所有信息都发送到数据库。接下来,我希望他们能够编辑该个人资料表单(电子邮件地址除外)。我希望我的编辑个人资料表单预先填充用户通过初始个人资料表单提交的值。
目前,随着用户填写个人资料信息,登录工作正常。所有信息都按预期发送到数据库。当用户编辑其个人资料时,所有个人资料信息都会按预期预先填充。问题是输入字段不可编辑。我可以单击输入字段来尝试更新它,但它会立即更新回原始状态。例如,如果我编辑名字杰西卡,我将单击该输入并按字母“a”上的退格键,该字母就会消失并立即重新出现。
我参考了 Supabase 文档和 React 文档,但我还没有找到有效的解决方案或示例,并且我的大部分代码此时都经过了反复试验。我不确定实际错误在哪里。
这是与状态更改相关的代码:
const [values, setValues] = useState(null);
const [findData, setFindData] = useState('');
const [email, setEmail] = useState('');
const [loading, setLoading] = useState(true);
这是我为获取登录用户的个人资料而编写的代码:
const getProfile = async () => {
const {
data: { user },
} = await supabase.auth.getUser();
const loadingTimer = setTimeout(() => {
setLoading(false);
setEmail(user.email);
setValues({ ...values, email: user.email });
}, 2000);
const { data, error } = await supabase
.from('clients')
.select()
.eq('email', user.email)
.single()
setFindData(data);
setValues(data);
};
useEffect(() => {
getProfile();
}, [loading, findData]);
我不确定这里是否需要
setFindData
,因为它与setValues
相同。
这是我的
handleChange
功能:
const handleChange = (e) => {
setValues({ ...values, [e.target.name]: e.target.value });
};
我的所有输入字段看起来都与
first_name
字段的示例类似:
<input
value={values.first_name}
id='first_name'
name='first_name'
type='text'
required
autoComplete='given-name'
onChange={handleChange}
className='block w-full rounded-md border-0 py-1.5 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-purpleDefault sm:leading-6'
/>
我不确定我做错了什么。如果我从
findData
中的依赖项数组中删除 useEffect
,数据将填充表单,然后几秒钟后消失。我还尝试在输入字段中使用 defaultValue={values.first_name}
而不是 value={values.first_name}
。该路线允许输入字段表现得好像它是可编辑的(这意味着我可以将 Jessica 更改为 Jess),但是当我查看我的 React 开发工具时,状态实际上并没有改变。
预计到达时间:我忘记在控制台中发布错误消息:
Warning: A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component.
我想发布我的答案,以防其他人将来遇到这个问题。我删除了
const [findData, setFindData] = useState('')
,因为它是不必要的。在 getProfile
函数中,我从数据库中提取数据的部分,我需要澄清数据是什么,所以我将该部分更改为 const { data: values, error}
。这样做允许我将值设置为 values
。我的依赖数组也不正确。我从数组中删除了 findData
并将其替换为 supabase
。这是相关更新的代码:
这是与状态更改相关的代码:
const [loading, setLoading] = useState(true);
const [email, setEmail] = useState('');
const [values, setValues] = useState('');
这是我为获取登录用户的个人资料而编写的代码:
const getProfile = async () => {
const {
data: { user },
} = await supabase.auth.getUser();
const loadingTimer = setTimeout(() => {
setLoading(false);
setEmail(user.email);
setValues({ ...values, email: user.email });
}, 2000);
const { data: values, error } = await supabase
.from('clients')
.select()
.eq('email', user.email)
.single();
setValues(values);
setPhone(values.phone);
};
useEffect(() => {
getProfile();
}, [loading, supabase]);