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

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


解决方案

问题根源

  1. 判断条件过于严格:原代码只判断ava === null,但实际场景中:
    • 组件初始化时ava的初始值是空字符串"",不满足=== null;
    • 当用户未登录或未设置头像时,user?.photoURL返回的是undefined,而非null,同样不触发判断。
  2. 缺少登录状态判断:未考虑用户完全未登录的情况,此时即使ava有值,也应该拦截。

修复步骤

  1. 修正ava的初始状态:将初始值改为null,和user?.photoURL的默认返回值保持一致:
const [ava, setAva] = useState(null);
  1. 优化判断逻辑:同时检查用户登录状态和头像是否存在,覆盖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);
    }
};
  1. 可选:优化Firestore写入逻辑:既然已经拦截了无头像的情况,写入时可以直接用ava,不需要再做ava ? ava : 'Anonymous'的判断。

内容的提问来源于stack exchange,提问作者Dan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 22:43:20