更新到Firebase版本9 onValue后,React本机内存泄漏错误



我正在更新Firebase版本9模块化表单的代码。我现在使用onValue。根据我所读到的内容,它返回一个删除侦听器的函数。但我仍然做得不好,因为尽管它一开始功能很好,但当我打开应用程序在后端更改数据库时,我会得到";不能对未安装的组件执行反应状态更新";当我在其他应用程序屏幕中时出错。请参阅下面的新旧代码。

旧代码:

useEffect(() => {
loadListings();
},[]);
const loadListings = async () => {  
setLoading(true);
updateInput('');
let testData = [];
let searchData = [];
db.ref('deals').once('value', (snapshot) =>{
snapshot.forEach((child)=>{
testData.push({
id: child.key,
title: child.val().hasOwnProperty('title') ? child.val().title : 'NA',
})
searchData.push(
child.val().title
)
}) 
})
.then(()=>{
checkMessages(testData);
setLoading(false);
})
.catch((error) => Sentry.Native.captureException('Error MessagesScreen function loadListings 1 ' + error));
}

新代码:

useEffect(() => {
loadListings();
},[]);
const loadListings = async () => {  
setLoading(true);
updateInput(''); 
const dbRef = ref(db, 'deals');
return onValue(dbRef , (snapshot) => {
let testData = [];
let searchData = [];
let storeData = filterStores;
snapshot.forEach((childSnapshot)=>{
testData.push({
id: childSnapshot.key,
title: childSnapshot.val().hasOwnProperty('title') ? childSnapshot.val().title : 'NA',
})
}) 
checkMessages(testData);
setLoading(false);
})
} 

在收到下面的答案后,我将useEffect改为这个,现在它起作用了:

useFocusEffect(
React.useCallback( () => {
async function fetchData() {
// You can await here
const response = await loadListings();
// ...
return () => response();
}
fetchData();
}, [])
);

您提到了从onValue返回的取消订阅函数。为了调用它,我认为您需要从调用中获取它,然后在一些导航状态更改时调用它。

假设您使用的是React Navigation,它可能看起来像这样(使用useFocusEffect

import { useFocusEffect } from '@react-navigation/native';
function YourComponent() {
const [loading, setLoading] = React.useState(false)
useFocusEffect(
React.useCallback(async () => {
const unsubscribe = await loadListings();
return () => unsubscribe();
}, [])
);
const loadListings = async () => {  
setLoading(true);
updateInput(''); 
const dbRef = ref(db, 'deals');
return onValue(dbRef , (snapshot) => {
let testData = [];
let searchData = [];
let storeData = filterStores;
snapshot.forEach((childSnapshot)=>{
testData.push({
id: childSnapshot.key,
title: childSnapshot.val().hasOwnProperty('title') ? childSnapshot.val().title : 'NA',
})
}) 
checkMessages(testData);
setLoading(false);
})
} 
return <View />;
}

另外,不要忘记将async/await用于异步loadListings函数,或者使用.then()。否则,你将面临一个悬而未决的承诺。

我还发现了一个相关的StackOverflow问题,它帮助我得到了这个答案。也许这对你有用。

相关内容

  • 没有找到相关文章

最新更新