如何从Firebase Database获取日期数据并展示在列表栏中?
问题分析与解决方案
你的代码核心问题在于React组件无法从异步回调中返回JSX,且异步操作完成后不会自动触发组件重新渲染。同时你直接操作auth.currentUser.reloadUserInfo的方式也不安全,因为currentUser可能在组件挂载时还未初始化。以下是修正后的完整实现:
修正后的代码
import React, { useState, useEffect } from 'react' import { RiDeleteBin6Line } from "react-icons/ri"; import { FaExchangeAlt } from "react-icons/fa"; import { ref, child, get } from 'firebase/database' import { getDatabase } from 'firebase/database' import { getAuth, onAuthStateChanged } from "firebase/auth"; export const CardDateList = () => { // 用状态管理数据、加载状态和错误信息 const [dateList, setDateList] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchDateData = async () => { try { const auth = getAuth(); // 等待用户认证状态初始化,避免currentUser为null const user = await new Promise((resolve) => { const unsubscribe = onAuthStateChanged(auth, (user) => { resolve(user); unsubscribe(); }); }); if (!user) { setError("用户未登录"); return; } const dbRef = ref(getDatabase()); // 获取用户对应的位置名称 const identifySnapshot = await get(child(dbRef, `locations/identify/${user.uid}`)); if (!identifySnapshot.exists()) { setError("无关联位置数据"); return; } const locationName = identifySnapshot.val().name; // 获取可用日期列表 const datesSnapshot = await get(child(dbRef, `locations/public/${locationName}/availabledates/`)); const dates = []; datesSnapshot.forEach(childSnapshot => { dates.push(childSnapshot.val()); }); setDateList(dates); } catch (err) { setError(err.message); console.error(err); } finally { setLoading(false); } }; fetchDateData(); }, []); // 加载状态提示 if (loading) return <div>加载日期数据中...</div>; // 错误状态提示 if (error) return <div>加载失败:{error}</div>; // 无数据提示 if (dateList.length === 0) return <div>暂无可用日期</div>; // 渲染日期列表 return ( <div className='container_date_element'> {dateList.map((dateItem, index) => ( <label key={dateItem.date || index}> <div className='container_date_list_element' id={dateItem.date}> <form className='form_date_list_element'> <div className='list_element'> <label>{dateItem.date}</label> <br /> <input /> </div> <div className='list_element'> <label>{dateItem.genre}</label> <br /> <input /> </div> <div className='list_date_button'> <button><FaExchangeAlt/></button> <button><RiDeleteBin6Line/></button> </div> </form> </div> </label> ))} </div> ); };
关键改动说明
- 状态管理:使用
useState存储日期列表、加载状态和错误信息,确保数据变化时组件自动重新渲染 - 异步逻辑规范:用
useEffect在组件挂载时执行异步数据请求,避免重复调用;改用async/await替代嵌套then回调,提升代码可读性 - 用户认证处理:通过
onAuthStateChanged等待用户认证状态初始化,避免直接访问currentUser导致的空值问题 - 列表渲染:使用
map遍历dateList数组,为每个日期项生成独立的UI元素,确保所有数据都能被渲染 - 状态反馈:添加加载、错误、空数据状态的UI提示,提升用户体验
内容的提问来源于stack exchange,提问作者Primo Centurio
相关产品推荐
相关产品推荐

