使用useEffect获取Firestore公开数据时遇内存泄漏警告问题
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
isMountedflag initialized totrueat the start ofuseEffectto track the component's mount status. - In both the
thenandcatchblocks, we first check ifisMountedis stilltruebefore calling any state setters—this ensures we don't try to update state on an unmounted component. - The cleanup function now sets
isMountedtofalse, 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




