You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用useEffect获取Firestore公开数据时遇内存泄漏警告问题

Fixing the "Can't perform React state update on unmounted component" Warning with Firestore get()

Hey there! Let's break down why you're seeing this warning and how to fix it.

The Root Cause

The warning pops up because your Firestore get() call returns a Promise, and if your component unmounts before that Promise resolves, the subsequent setEvents or setLoading calls try to update state on a component that no longer exists. Your current cleanup function just returns the Promise (info), which doesn't actually cancel the async operation or prevent the state updates—it's effectively doing nothing to fix the issue.

The Solution: Track Component Mount Status

Since get() doesn't have an unsubscribe method like onSnapshot, we can use a simple flag to track whether the component is still mounted. When the Promise resolves or rejects, we'll check this flag before updating state.

Here's your modified code:

useEffect(() => { 
  let isMounted = true; // Flag to track if component is still mounted
  let list = [];
  const db = firebase.firestore().collection('events');

  db.where('public', '==', 'public').get()
    .then(snapshot => {
      // Skip state updates if component is already unmounted
      if (!isMounted) return;

      if (snapshot.empty) { 
        console.log('No matching documents.'); 
        setLoading(false);
        return; 
      } 

      snapshot.forEach(doc => { 
        console.log(doc.id, "=>", doc.data());
        list.push({ id: doc.id, ...doc.data() });
      }); 

      setEvents(list);
      setLoading(false);
    }) 
    .catch(error => {
      // Skip state updates if component is already unmounted
      if (!isMounted) return;

      setLoading(false);
      console.log('error => ', error);
    });

  // Cleanup function: mark component as unmounted when it unmounts
  return () => {
    isMounted = false;
  };
}, []);

What Changed?

  • Added an isMounted flag initialized to true at the start of useEffect to track the component's mount status.
  • In both the then and catch blocks, we first check if isMounted is still true before calling any state setters—this ensures we don't try to update state on an unmounted component.
  • The cleanup function now sets isMounted to false, so if the Firestore Promise resolves after the component has unmounted, we skip all state updates entirely.

This approach eliminates the memory leak warning without needing to cancel the Firestore request directly, since get() doesn't support cancellation natively.

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

火山引擎 最新活动