React Native习惯追踪应用:如何从Firebase Firestore获取数据并调整样式
React Native习惯追踪应用:Firebase数据获取与日历样式调整
一、Firebase基础配置
- 先安装Firebase依赖:
npm install firebase # 或者用yarn yarn add firebase
- 创建Firebase配置文件(比如
firebaseConfig.js),填入你的项目配置信息:
import { initializeApp } from "firebase/app"; import { getFirestore } from "firebase/firestore"; const firebaseConfig = { apiKey: "你的API密钥", authDomain: "你的认证域名", projectId: "你的项目ID", storageBucket: "你的存储桶地址", messagingSenderId: "你的消息发送者ID", appId: "你的APP ID" }; const app = initializeApp(firebaseConfig); export const db = getFirestore(app);
二、修改日历组件,对接Firebase数据
你原来的组件存在逻辑问题:不能在map循环里声明useState,这会导致每个日期项生成独立状态,引发逻辑混乱。下面是调整后的完整代码,实现从Firebase获取数据、根据数据渲染样式,以及点击更新Firestore数据的功能:
import { useState, useEffect } from 'react'; import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'; import { db } from './firebaseConfig'; import { doc, getDoc, updateDoc } from "firebase/firestore"; const days = ['M', 'T', 'W', 'T', 'F', 'S', 'S']; // 这里要和你Firestore文档里的日期字段名完全对应,比如你的文档里是mon、tue就填这个,要是直接用M、T就改成['M','T','W','T','F','S','S'] const dayFields = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']; const Calendar = ({ habitId }) => { // 存储从Firebase获取的日期完成状态 const [dayStatus, setDayStatus] = useState({}); // 组件挂载时获取Firestore数据 useEffect(() => { const fetchHabitData = async () => { // 假设你的习惯数据存在名为habits的集合里,每个习惯对应一个文档,habitId是文档ID const docRef = doc(db, "habits", habitId); const docSnap = await getDoc(docRef); if (docSnap.exists()) { setDayStatus(docSnap.data()); } else { console.log("未找到对应的习惯数据"); } }; fetchHabitData(); }, [habitId]); // 点击日期时更新Firebase数据和本地状态 const toggleDayCompletion = async (index) => { const fieldName = dayFields[index]; const newStatus = !dayStatus[fieldName]; // 更新Firestore文档 const docRef = doc(db, "habits", habitId); await updateDoc(docRef, { [fieldName]: newStatus }); // 同步更新本地状态 setDayStatus(prev => ({ ...prev, [fieldName]: newStatus })); }; return ( <View style={styles.calendarWrap}> {days.map((day, index) => { // 根据Firebase里的字段值判断是否完成 const isCompleted = dayStatus[dayFields[index]] === true; return ( <View style={styles.dayWrap} key={index}> <Text style={styles.day}>{day}</Text> <TouchableOpacity style={[styles.weekCircle, isCompleted && { backgroundColor: '#000' }]} onPress={() => toggleDayCompletion(index)} /> </View> ); })} </View> ); }; const styles = StyleSheet.create({ calendarWrap: { flexDirection: 'row', justifyContent: 'space-around', alignItems: 'center', paddingVertical: 10 }, dayWrap: { alignItems: 'center' }, day: { fontSize: 16, marginBottom: 5 }, weekCircle: { width: 30, height: 30, borderRadius: 15, borderWidth: 1, borderColor: '#ccc' } }); export default Calendar;
三、关键逻辑说明
- 数据获取:用
useEffect在组件挂载时调用getDoc从Firestore拉取对应习惯的文档数据,存入dayStatus状态。 - 样式控制:遍历日期时,通过
dayStatus[fieldName]判断该日期是否为true,如果是就给TouchableOpacity加上黑色背景样式。 - 数据更新:点击日期时调用
updateDoc修改Firestore对应字段的值,同时同步更新本地状态,确保UI实时变化。
注意:dayFields数组必须和你Firestore文档里的日期字段名完全一致,比如你的文档里用M作为周一的字段名,就把数组改成['M','T','W','T','F','S','S']。
内容的提问来源于stack exchange,提问作者nura
相关产品推荐
相关产品推荐

