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

React中使用Firebase getDocs与useEffect出现两次请求的问题

React中useEffect执行两次导致重复获取Firebase数据的解决方案

问题原因

  • React 18的开发模式下,StrictMode会自动执行两次挂载相关的生命周期(包括useEffect),这是官方刻意设计的机制,用来帮开发者检测组件中可能存在的副作用问题,生产环境下不会触发该行为。
  • 你的代码中,setMusicList采用循环追加旧数组的方式更新状态,两次执行getData会直接导致数据重复叠加。

修复步骤

1. 先解决数据重复问题

修改getData函数,一次性整理所有Firebase返回的数据后再更新状态,避免多次调用setState,同时从根源上杜绝重复数据:

const getData = async () => {
  try {
    const querySnapshot = await getDocs(collection(db, "music"));
    // 一次性转换所有文档数据为数组,再更新状态
    const newMusicList = querySnapshot.docs.map(doc => doc.data());
    setMusicList(newMusicList);
    console.log("Did request!");
  } catch (error) {
    console.log(error);
  }
};

2. 处理StrictMode导致的两次请求(可选)

如果想在开发模式下彻底避免两次请求,可通过添加标志位控制:

useEffect(() => {
  let isMounted = true;
  const fetchData = async () => {
    // 组件卸载或重复执行时直接终止逻辑
    if (!isMounted) return;
    try {
      const querySnapshot = await getDocs(collection(db, "music"));
      const newMusicList = querySnapshot.docs.map(doc => doc.data());
      setMusicList(newMusicList);
      console.log("Did request!");
    } catch (error) {
      console.log(error);
    }
  };
  fetchData();
  // 组件卸载时重置标志位
  return () => {
    isMounted = false;
  };
}, []);

这种方式既能保留StrictMode的检测能力,又能避免无效的重复请求。

额外说明

生产环境打包后,StrictMode会自动失效,不会出现两次执行的情况。开发模式下的两次执行是React用来提前暴露潜在问题(比如内存泄漏、重复订阅)的机制,建议不要长期移除StrictMode。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:25:48