React/NextJS问题:ava值为null时为何未触发评论拦截
问题:未设置头像/未登录用户仍可添加评论,判断逻辑失效
我想要阻止未设置头像(或未登录)的用户添加评论,但当前逻辑不生效——即使控制台日志显示ava值确实为null,评论依然能成功添加到Firestore后端,页面状态也会更新为新评论,搞不懂为什么判断逻辑没触发错误拦截。
相关代码如下:
组件初始化与监听代码
import { addDoc, getFirestore, collection, serverTimestamp } from 'firebase/firestore'; import { getAuth } from "firebase/auth"; import { useRouter } from 'next/router'; const db = getFirestore() const auth = getAuth(); const Addcomment = ({ recipeId }) => { const router = useRouter() const [user, setUser] = useState(auth.currentUser); const [displayName, setDisplayName] = useState(user?.displayName); const [ava, setAva] = useState(""); const [writeComment, setWriteComment] = useState("") const [successMessage, setSuccessMessage] = useState(""); const [error, setError] = useState(""); const [openSnackbar, setOpenSnackbar] = useState(false); useEffect(() => { const unsubscribe = auth.onAuthStateChanged((user) => { setUser(user); setDisplayName(user?.displayName); setAva(user?.photoURL); }); return () => unsubscribe(); }, []);
提交处理函数
const handleSubmit = async (e) => { console.log(ava) e.preventDefault(); if (ava === null) { setError("You must have an avatar to add a comment, please update your profile in the top right corner."); console.error("Avatar not set"); console.log(ava) setTimeout(() => { router.push('/profile'); }, 3000); return } else { try { await addDoc(collection(db, "comments"), { postedBy: displayName ? displayName : 'Anonymous', avatar: ava ? ava : 'Anonymous', text: writeComment, recipeId: recipeId, createdAt: serverTimestamp() }); setWriteComment(""); setSuccessMessage("Comment added successfully"); setOpenSnackbar(true); } catch (err) { setError("Error occurred while adding the comment."); console.error("Error:", err); } } };
控制台日志截图

解决方案
问题根源
- 判断条件过于严格:原代码只判断
ava === null,但实际场景中:- 组件初始化时
ava的初始值是空字符串"",不满足=== null; - 当用户未登录或未设置头像时,
user?.photoURL返回的是undefined,而非null,同样不触发判断。
- 组件初始化时
- 缺少登录状态判断:未考虑用户完全未登录的情况,此时即使
ava有值,也应该拦截。
修复步骤
- 修正
ava的初始状态:将初始值改为null,和user?.photoURL的默认返回值保持一致:
const [ava, setAva] = useState(null);
- 优化判断逻辑:同时检查用户登录状态和头像是否存在,覆盖
null、undefined、空字符串等所有无效情况:
const handleSubmit = async (e) => { console.log(ava); e.preventDefault(); // 未登录 或 未设置头像,直接拦截 if (!user || !ava) { setError("你需要登录并设置头像才能添加评论,请点击右上角更新你的资料。"); console.error("未登录或未设置头像"); setTimeout(() => { router.push('/profile'); }, 3000); return; } // 正常提交逻辑 try { await addDoc(collection(db, "comments"), { postedBy: displayName || 'Anonymous', avatar: ava, text: writeComment, recipeId: recipeId, createdAt: serverTimestamp() }); setWriteComment(""); setSuccessMessage("评论添加成功"); setOpenSnackbar(true); } catch (err) { setError("添加评论时发生错误。"); console.error("错误:", err); } };
- 可选:优化Firestore写入逻辑:既然已经拦截了无头像的情况,写入时可以直接用
ava,不需要再做ava ? ava : 'Anonymous'的判断。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

