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

React+Firebase实现带导航的文档按钮数组问题排查

问题:Firebase Firestore数据渲染按钮数组失败的错误分析与修复

需求说明

  • 从Cloud Firestore的Curso集合中获取所有文档
  • 将文档数据转化为按钮数组渲染到页面
  • 每个按钮点击时携带对应文档的完整信息,导航至/LimpiarCurso页面供后续使用

此前可行的实现(JSON数据+map)

{aulas.map((aula) => (
  <div key={aula.id} className="col-md-4" style={{paddingBottom: '10px', paddingTop: '5px'}}>
    <Button className={(aula.estado==='sucio'? 'btn btn-danger': 'btn btn-success')} 
    onClick={()=> navigate('/LimpiarCurso',
    {state: {id:aula.id,num_aula:aula.num_aula,año:aula.año,
    division:aula.division,horario_retiro:aula.horario_retiro}})}>
      {aula.año}{aula.division}
    </Button>
  </div>
))}

当前Firebase版本的错误代码

export default function AdministrarCurso(){
    const navigate= useNavigate();
    function mostrarCursos(navigate){
        const querySnapshot = getDocs(collection(db, "Curso"));
        querySnapshot.forEach((doc) => {
            // console.log(doc);
            // console.log(doc.data());
            console.log(doc.get('anio')+doc.get('division'));
            <div className="col-md-4" style={{paddingBottom: '10px', paddingTop: '5px'}}>
            <Button 
            className={(doc.get('estado')==='sucio'? 'btn btn-danger': 'btn btn-success')} 
            onPress={()=> navigate('/LimpiarCurso',
            {state: doc.data()})}>
                {doc.get('anio')+doc.get('division')}
            </Button>
            </div>
    });
    }
    return(
        <Container> 
            <AppBar style={{background: 'transparent', boxShadow: 'none'}}>
                <Toolbar>
                    <Button onClick={()=> LogOut(navigate)}>Cerrar Sesión</Button>
                </Toolbar>
            </AppBar>
             <div className="row">
             
            {mostrarCursos()}
                 {/* Acá hay botones que se generan en base a la cantidad de documentos que tenga el forEach
//                 Que te redireccionan a la pantalla de Limpiar Curso
//                  */}
             </div>
         </Container>
     )
 }

遇到的错误

  • 初始错误:Objects are not valid as a react child
  • 调整后错误:querySnapshot 不是函数

错误原因与修复方案

1. 异步函数处理错误

getDocs是异步函数,直接赋值会得到Promise对象而非查询快照,导致forEach调用失败。必须用async/await配合useEffect在组件挂载时异步获取数据。

2. 未正确返回JSX元素

mostrarCursos函数没有收集并返回生成的JSX元素,React无法渲染undefined或Promise对象,引发“无效React子元素”错误。需要用状态存储文档数据,再通过map遍历生成按钮。

3. 事件名错误

Web React中按钮点击事件应为onClick,而非React Native的onPress,否则点击逻辑不会触发。

修正后的完整代码

import { useState, useEffect } from 'react';
import { getDocs, collection } from 'firebase/firestore';
import { useNavigate } from 'react-router-dom';
import { Container, AppBar, Toolbar, Button } from '@mui/material'; // 按实际使用的组件库调整

export default function AdministrarCurso(){
    const navigate = useNavigate();
    const [cursos, setCursos] = useState([]);

    // 组件挂载时异步获取Firestore数据
    useEffect(() => {
        const fetchCursos = async () => {
            const querySnapshot = await getDocs(collection(db, "Curso"));
            // 将文档数据转换为包含id的数组
            const cursosData = querySnapshot.docs.map(doc => ({
                id: doc.id,
                ...doc.data()
            }));
            setCursos(cursosData);
        };
        fetchCursos();
    }, []);

    return(
        <Container> 
            <AppBar style={{background: 'transparent', boxShadow: 'none'}}>
                <Toolbar>
                    <Button onClick={()=> LogOut(navigate)}>Cerrar Sesión</Button>
                </Toolbar>
            </AppBar>
             <div className="row">
                {cursos.map((curso) => (
                    <div key={curso.id} className="col-md-4" style={{paddingBottom: '10px', paddingTop: '5px'}}>
                        <Button 
                            className={curso.estado === 'sucio' ? 'btn btn-danger' : 'btn btn-success'}
                            onClick={() => navigate('/LimpiarCurso', { state: curso })}
                        >
                            {curso.anio}{curso.division}
                        </Button>
                    </div>
                ))}
             </div>
         </Container>
     )
 }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 15:10:26