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

React中设置span背景色时出现TypeError报错求助

解决React运行时错误:TypeError: Cannot read properties of undefined (reading 'color')

问题场景

跟随Jonas Schmedtmann的全栈速成课程学习,编写与课程一致的代码时出现上述错误,错误关联代码为Fact组件中设置标签背景色的部分。

错误关联代码

<span
    className="tag"
    style={{
        backgroundColor: CATEGORIES.find((cat) => cat.name === fact.category)
            .color,
        }}
    onClick={() => setCurrentCategory(fact.category)}>
    {fact.category}
</span>

完整Fact组件代码

function Fact({ fact, setCurrentCategory, setFacts }) {
    const [isUpdating, setIsUpdating] = useState(false);
    async function handleVote(vote) {
        if (vote) {
            setIsUpdating(true);
            const { data: updatedFact, error } = await supabase
                .from("facts")
                .update({ [vote]: fact[vote] + 1 })
                .eq("id", fact.id)
                .select();
            if (!error) {
                setIsUpdating(false);
                setFacts((facts) =>
                    facts.map((f) => (f.id === fact.id ? updatedFact[0] : f))
                );
            }
        }
    }

    return (
        <li className="fact">
            <p>
                {fact.text}
                <a
                    className="source"
                    href={fact.source}
                    target="_blank"
                    rel="noreferrer">
                    (Source)
                </a>
            </p>
            <span
                className="tag"
                style={{
                    backgroundColor: CATEGORIES.find((cat) => cat.name === fact.category)
                      .color,
                  }}
                onClick={() => setCurrentCategory(fact.category)}>
                {fact.category}
            </span>
            <div className="vote-buttons">
                <button
                    onClick={() => handleVote("vote_interesting")}
                    disabled={isUpdating}>
                    👍 {fact.vote_interesting}
                </button>
                <button
                    onClick={() => handleVote("vote_mindBlowing")}
                    disabled={isUpdating}>
                    🤯 {fact.vote_mindBlowing}
                </button>
                <button onClick={() => handleVote("vote_false")} disabled={isUpdating}>
                    ⛔ {fact.vote_false}
                </button>
            </div>
        </li>
    );
}

分类与颜色定义数组

const CATEGORIES = [
    { name: "technology", color: "#3b82f6" },
    { name: "science", color: "#16a34a" },
    { name: "finance", color: "#ef4444" },
    { name: "society", color: "#eab308" },
    { name: "entertainment", color: "#db2777" },
    { name: "health", color: "#14b8a6" },
    { name: "history", color: "#f97316" },
    { name: "news", color: "#8b5cf6" }
];

错误原因

核心问题是CATEGORIES.find((cat) => cat.name === fact.category)返回了undefined,导致尝试读取color属性时触发错误。可能的诱因:

  • fact.category的值与CATEGORIES数组中name字段不匹配(比如大小写差异、拼写错误,例如数据库中存的是"Technology"而数组中是"technology")
  • 组件渲染时fact.category可能处于临时的null/undefined状态(即使每个fact理论上都有category,初始加载或数据同步阶段可能存在异常)

解决方案

1. 添加空值保护(快速修复)

使用可选链操作符?.避免读取undefined的属性,同时设置默认颜色兜底:

style={{
    backgroundColor: CATEGORIES.find((cat) => cat.name === fact.category)?.color || '#ccc'
}}

2. 检查数据一致性

  • 查看Supabase数据库中facts表的category字段值,确保与CATEGORIES数组中的name完全一致(大小写、拼写必须严格匹配)
  • 可在组件中添加日志排查具体值:
// 在Fact组件的return前添加
console.log('当前fact的category:', fact.category);
console.log('匹配到的分类:', CATEGORIES.find((cat) => cat.name === fact.category));

3. 优化分类查找方式(可选)

提前构建分类到颜色的映射对象,提升查找性能和代码可读性:

// 定义在组件外部或合适的位置
const CATEGORY_COLOR_MAP = Object.fromEntries(
    CATEGORIES.map(cat => [cat.name, cat.color])
);

// 在组件中使用
style={{
    backgroundColor: CATEGORY_COLOR_MAP[fact.category] || '#ccc'
}}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 07:57:33