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

React中state数组存入Firebase数据后map方法不渲染问题

问题原因
  • 违反React状态不可变原则:你直接对useState返回的状态变量allScores执行push操作,全程没有调用配套的状态更新方法setAllScores。React无法感知到这种直接修改原状态的操作,不会触发组件重渲染,组件渲染阶段读取到的allScores始终是初始值空数组,map遍历自然不会生成任何节点。
  • 遍历渲染时的place变量未定义,没有初始化逻辑,即便状态正常更新,这里也会抛出引用错误导致渲染失败。
修复方案
  1. 从Firebase拉取数据时,先把所有文档数据组装到临时数组里,拉取完成后调用setAllScores把临时数组作为新状态传入,触发组件重渲染。
  2. 排名计算直接使用Array.map自带的第二个索引参数,不需要额外维护计数变量,同时给列表项加上唯一key属性,保证React渲染性能和正确性。

修复后的完整代码:

const [allScores,setAllScores] = useState([])

async function getAllScores(){
    const q = query(collection(db, "allScores"), orderBy("score", "desc"));
    const querySnapshot = await getDocs(q);
    const resList = []
    querySnapshot.forEach((doc) => {
        resList.push(doc.data())
    })
    // 调用状态更新方法,通知React数据变化需要重渲染
    setAllScores(resList)
}

useEffect(() => {
    getAllScores()
}, [])

<table className="text-white text-center">
    <tbody>
        <tr>
            <td className="px-[205px] text-xl">Place</td>
            <td className="px-[205px] text-xl">User</td>
            <td className="px-[205px] text-xl">Score</td>
            <td className="px-[205px] text-xl">Scored at</td>
        </tr>
        {allScores.map((score, index) => (
            <tr key={score.playerName + index}>
                <td className="px-[205px] text-xl w-auto">{index + 1}</td>
                <td className="px-[205px] text-xl w-auto">{score.playerName}</td>
                <td className="px-[205px] text-xl w-auto">{score.score}</td>
                {/* <td className="px-[210px] text-xl">{score.scoredAt}</td> */}
            </tr>
        ))}
    </tbody>
</table>

提示:如果你的Firebase文档有唯一ID字段,优先用文档ID作为tr节点的key值,比用户名加索引的组合更稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:06:28