React+Firebase新增分类后如何实时更新数组状态无需刷新?
问题:新增分类后无法实时展示,需刷新页面
我正在使用React和Firebase搭建首个项目,在Header.jsx组件中通过映射展示所有已添加的分类名称,但新增分类后,新分类名称无法实时显示,仅刷新页面才会出现。我推测是未更新data状态导致,请问如何无需刷新页面就能更新数组状态并展示新分类?
相关代码
const [data, setData] = useState([]); // 获取Firebase中的所有分类 useEffect(() => { const fetchData = async () => { let list = [] try{ const categories = collection(db, 'category') let mquery = query(categories, orderBy('timeStamp', "desc")) const querySnapshot = await getDocs(mquery); querySnapshot.forEach((doc) => { list.push({ id: doc.id, ...doc.data()}); }); setData(list); } catch (err) { console.log(err) } }; fetchData() }, []); // 在Header中映射分类名称 <ul className="absolute hidden text-white pt-1 group-hover:block items-center"> {data.map((category, index) => { return ( <Link to={`/categories/${category.name}`} key={category.id}> <li className='rounded-lg p-2 hover:text-white/80 hover:-translate-y-1 hover:scale-110 duration-300 transition ease-in-out delay-150'> <span>{category.name}</span> </li> {/* 注意:原代码此处标签未正确闭合 */} </Link> ) })} </ul>
解决方案
你当前使用的getDocs是一次性获取数据的方法,仅在组件首次挂载时执行一次,所以新增分类后无法自动更新。要实现实时同步,需要改用Firebase的实时快照监听功能onSnapshot,它会在数据初始加载、新增、修改或删除时自动触发回调,更新状态。
修改后的useEffect代码如下:
const [data, setData] = useState([]); useEffect(() => { const categories = collection(db, 'category'); const mquery = query(categories, orderBy('timeStamp', "desc")); // 订阅数据的实时变化 const unsubscribe = onSnapshot(mquery, (querySnapshot) => { const list = []; querySnapshot.forEach((doc) => { list.push({ id: doc.id, ...doc.data() }); }); setData(list); }, (error) => { console.error('监听分类数据出错:', error); }); // 组件卸载时取消订阅,避免内存泄漏 return () => unsubscribe(); }, []);
说明
onSnapshot会立即返回当前的数据集,之后每次数据有变化时都会重新触发回调,自动更新data状态,页面随之渲染最新分类- 必须返回取消订阅的函数
unsubscribe,在组件卸载时执行,防止不必要的资源占用 - 顺便修正了原代码中
<li>标签未正确闭合的问题,避免DOM渲染错误
内容的提问来源于stack exchange,提问作者paniklas
相关产品推荐
相关产品推荐

