如何在Expo的React Native Agenda组件中展示Firebase数据
解决React Native Agenda组件结合Firebase实时数据库的渲染问题
问题描述
我尝试展示从Firebase实时数据库获取的数据,但不知道如何将useState中的data变量传入Agenda组件的renderItem()方法中使用。我已通过useState创建了可用于map的键,希望找到方法将这些变量取出并在react-agenda中使用。
相关代码
import React, { useEffect, useState } from 'react' import { StyleSheet, View, Text, TouchableOpacity, Modal, TextInput, Alert } from 'react-native' import { LocaleConfig, Agenda } from 'react-native-calendars' import DateTimePicker from 'react-native-modal-datetime-picker'; import { getAuth } from 'firebase/auth'; import { getDatabase, ref, onValue, set, push, get, child } from 'firebase/database'; const Calendario = () => { const [modalVisible, setModalVisible] = useState(false); const [events, setEvents] = useState(''); const [dateSelected, setDateSelected] = useState(''); const [description, setDescription] = useState(''); const [refreshCalender, setRefreshCalender] = useState(false); const [isDatePickerVisible, setDatePickerVisibility] = useState(false); const [data, setmyData]=useState({}) const db = getDatabase(); const app = getAuth(); const refe = ref(db, 'users/' + app.currentUser.uid); const dbRef = ref(db); const renderItem = (item, data) => { return( data.map(() => { <View style={styles.itemContainer}> <Text id={item["$key"]} style={styles.textInf}>{item.title}</Text> <Text style={styles.textInf}>{item.details}</Text> </View> }) ) } const storeInDB = () => { push(refe, { date: strDate, title: events, details: description }); } useEffect(()=>{ onValue(ref(db, 'users/' + app.currentUser.uid), snapshot =>{ let data = []; snapshot.forEach(childsnap => { let val = childsnap.val(); val['$key'] = childsnap.key; data.push(val); }); setmyData(data); }) },[]); return ( <> <Agenda //items={ dataF } renderEmptyDate={() => { return <View />; }} renderEmptyData={() => { return <View />; }} selected={new Date()} minDate={null} renderItem={renderItem} markingType="custom" refreshing={refreshCalender} /> </> ) } export default Calendario
Firebase实时数据库数据截图

解决方案
1. 转换数据格式适配Agenda要求
Agenda组件的items属性需要以日期字符串(YYYY-MM-DD)为键、对应日期的事件数组为值的对象结构。需要把Firebase返回的数组转换成这种格式:
useEffect(()=>{ onValue(ref(db, 'users/' + app.currentUser.uid), snapshot =>{ const agendaItems = {}; snapshot.forEach(childsnap => { const val = childsnap.val(); val['$key'] = childsnap.key; // 确保date字段是YYYY-MM-DD格式,若Firebase中格式不符需额外转换 const dateKey = val.date; // 初始化对应日期的数组 if (!agendaItems[dateKey]) { agendaItems[dateKey] = []; } agendaItems[dateKey].push(val); }); setmyData(agendaItems); // 更新为符合要求的格式 }) },[]);
2. 给Agenda组件绑定items属性
在Agenda标签中添加items={data},让组件能拿到事件数据:
<Agenda items={data} // 传入转换后的事件数据 renderEmptyDate={() => <View />} renderEmptyData={() => <View />} selected={new Date()} minDate={null} renderItem={renderItem} markingType="custom" refreshing={refreshCalender} />
3. 修正renderItem方法
Agenda的renderItem会自动接收当前日期下的单个事件作为参数,不需要手动遍历整个data数组,修改后:
const renderItem = (item) => { return ( <View style={styles.itemContainer}> <Text id={item.$key} style={styles.textInf}>{item.title}</Text> <Text style={styles.textInf}>{item.details}</Text> </View> ) }
4. 补充样式(可选)
如果没有定义样式,添加以下代码确保事件卡片正常显示:
const styles = StyleSheet.create({ itemContainer: { backgroundColor: '#fff', borderRadius: 6, padding: 12, marginVertical: 6, marginHorizontal: 10, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 3, }, textInf: { fontSize: 14, color: '#333', marginBottom: 4, } });
内容的提问来源于stack exchange,提问作者Hond4
相关产品推荐
相关产品推荐

