You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React项目中Firebase Firestore读取数据重复两次的问题求助

解决Firestore数据读取重复的问题

嘿,我帮你找到了数据重复的原因和解决办法:

问题根源

  1. React 18 Strict Mode的影响:在开发环境下,React 18的Strict Mode会自动让useEffect执行两次,目的是帮你检测潜在的副作用问题。
  2. State更新方式不对:你现在的代码是在forEach循环里逐个调用setPosts((posts) => [...posts, payload]),每次都往现有数组里追加数据。第一次执行fetchData时把所有文档都加到数组里,第二次执行时又重新遍历所有文档再追加一遍,结果就导致数据重复了。

修复方案

最直接的办法是先把所有Firestore文档数据收集到一个完整的数组里,再一次性更新state,这样即使useEffect执行两次,每次都是用新的完整数组替换旧数组,不会出现累加重复的情况。

修改后的useEffect代码如下(两种写法任选其一):

写法1:用forEach收集数据

useEffect(() => {
  const fetchData = async () => {
    const postRef = collection(db, 'posts');
    const postSnap = await getDocs(postRef);
    // 先创建一个空数组,收集所有文档数据
    const fetchedPosts = [];
    postSnap.forEach(doc => {
      const payload = { id: doc.id, ...doc.data() };
      fetchedPosts.push(payload);
    });
    // 一次性设置整个数组
    setPosts(fetchedPosts);
  }
  fetchData()
    .catch(console.error);
}, [])

写法2:用map更简洁

useEffect(() => {
  const fetchData = async () => {
    const postRef = collection(db, 'posts');
    const postSnap = await getDocs(postRef);
    // 直接用map把docs转换成我们需要的数组格式
    const fetchedPosts = postSnap.docs.map(doc => ({
      id: doc.id,
      ...doc.data()
    }));
    setPosts(fetchedPosts);
  }
  fetchData()
    .catch(console.error);
}, [])

额外优化建议

你现在在渲染PostSnippet时用了idx作为key,这其实不太推荐——如果数组顺序变化或者内容更新,React可能会出现渲染异常。建议换成每个文档唯一的article.id作为key:

{ _.map(posts, (article) => {
  return (
    <PostSnippet 
      key={article.id} 
      id={article.id} 
      title={article.title} 
      content={article.content.substring(0, 300)} 
    />
  )
}) }

这样修改后,不管是开发环境还是生产环境,数据都不会再重复啦~

内容的提问来源于stack exchange,提问作者Udayendu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 19:07:26