React+Firestore疫苗应用:点击按钮更新文档NoofDose字段
React + Firestore 实现疫苗中心剂量实时递减
核心思路
- 用Firestore的原子增量操作修改
NoofDose,避免并发更新冲突 - 通过
onSnapshot实时监听集合数据变化,实现页面自动刷新
具体实现步骤
1. 导入必要的Firebase工具
确保已完成Firebase初始化,导入所需方法:
import { getFirestore, collection, doc, updateDoc, FieldValue, onSnapshot } from "firebase/firestore";
2. 组件内实时获取并监听疫苗中心数据
用useState存储数据,通过useEffect设置快照监听,数据变化时自动更新组件状态:
import { useState, useEffect } from 'react'; import { getFirestore, collection, doc, updateDoc, FieldValue, onSnapshot } from "firebase/firestore"; const VaccinationCentres = () => { const [centres, setCentres] = useState([]); const db = getFirestore(); useEffect(() => { // 监听集合数据变化,自动同步到组件状态 const unsubscribe = onSnapshot(collection(db, 'VaccinationCentre'), (snapshot) => { const centresData = snapshot.docs.map(doc => ({ id: doc.id, // 必须保留文档ID,用于后续更新操作 ...doc.data() })); setCentres(centresData); }); // 组件卸载时取消监听,避免内存泄漏 return () => unsubscribe(); }, [db]); // 剂量递减函数、渲染逻辑... }
3. 实现剂量递减函数
点击Apply按钮时调用该函数,先判断剩余剂量是否合法,再执行原子更新:
const handleApply = async (centreId, currentDose) => { if (currentDose <= 0) { alert('当前无可用剂量'); return; } try { const centreRef = doc(db, 'VaccinationCentre', centreId); // 原子操作:安全将剂量减1,避免并发冲突 await updateDoc(centreRef, { NoofDose: FieldValue.increment(-1) }); } catch (error) { console.error('剂量更新失败:', error); } }
4. 渲染卡片并绑定按钮事件
遍历数据渲染卡片,每个按钮绑定对应文档的ID和当前剂量:
return ( <div className="centres-container"> {centres.map(centre => ( <div key={centre.id} className="centre-card"> <h3>{centre.Centrename}</h3> <p>地区:{centre.State} - {centre.District}</p> <p>剩余剂量:{centre.NoofDose}</p> <button onClick={() => handleApply(centre.id, centre.NoofDose)}> Apply </button> </div> ))} </div> );
关键注意事项
- 必须保留文档
id:更新文档时需要通过ID定位到具体条目,快照处理时务必将doc.id加入数据对象 - 优先使用
FieldValue.increment:该原子操作能保证多用户同时操作时数据的正确性,避免出现负数或计数错误 - 依赖
onSnapshot实现实时更新:无需手动刷新,集合数据变化时会自动触发组件状态更新
内容的提问来源于stack exchange,提问作者Vaishnavi S
相关产品推荐
相关产品推荐

