React native FCM-messaging().onMessage重复回调-不使用useEffect卸载
我正在使用FCM将消息发送到Android应用程序,然后将消息呈现到FlatList组件中。收到新FCM消息后,我希望刷新扁平列表组件,以便在列表中显示最新消息。我正在使用useEffect通过setRefreshPage()触发刷新 下面的代码工作得很好,除了每次接收到FCM消息并激发useEffect时,它似乎会创建第二个前台侦听器,从而导致后续消息的重复通知。我不认为取消订阅消息();正在删除useEffect中的现有前台侦听器 每次回调加倍,即第一次收到消息时回调1个FCM消息,然后下一条消息回调2个,下一条消息回调4个,等等。这让我觉得在每个useEffect触发器上都创建了额外的message().onMessage前台侦听器 触发useEffect时,删除消息传递侦听器的正确方法是什么 到目前为止,我只在Android上测试过这段代码React native FCM-messaging().onMessage重复回调-不使用useEffect卸载,react-native,react-native-firebase,React Native,React Native Firebase,我正在使用FCM将消息发送到Android应用程序,然后将消息呈现到FlatList组件中。收到新FCM消息后,我希望刷新扁平列表组件,以便在列表中显示最新消息。我正在使用useEffect通过setRefreshPage()触发刷新 下面的代码工作得很好,除了每次接收到FCM消息并激发useEffect时,它似乎会创建第二个前台侦听器,从而导致后续消息的重复通知。我不认为取消订阅消息();正在删除useEffect中的现有前台侦听器 每次回调加倍,即第一次收到消息时回调1个FCM消息,然后下一
function HomeScreen() {
const [data, setData] = useState([]);
const [refreshPage, setRefreshPage] = useState(false);
useEffect(async () => {
const value = await AsyncStorage.getItem('storedMessages');
// ...functions to retrieve and sort historical messages into array "sortedInput"
setData(sortedInput); // setState to provide initial data for FlatList component
};
const unsubscribeOnMessage = messaging().onMessage(async remoteMessage => {
console.log("DEBUG: Received FCM message: " + JSON.stringify(remoteMessage));
// Function to process new message and insert into local storage
await _handleNewMessage(remoteMessage);
// Display notification to user
await onDisplayNotification(remoteMessage);
// Trigger refresh of FlatList component with setState
setRefreshPage(Math.random() * 100);
});
return () => {
unsubscribeOnMessage();
};
}, [refreshPage]);
// Render messages into FlatList view
function renderMessagesFlatList(data) {
if (isLoading) {
return (
<ActivityIndicator
size="large"
color="#0000ff"
/>
);
} else if (data.length === 0) {
return (
<Text>No notifications to display</Text>
);
} else {
return (
<FlatList
data={data}
keyExtractor={(item, index) => item.id}
renderItem={({ item }) => (
<>
<View style={{ flexDirection: 'row', flex: 1 }}>
<Image
style={{ width: 40, height: 40 }}
source={{uri:item.icon}}
/>
<View style={{ flex: 1, paddingLeft: 5 }}>
<Text style={{ color: '#000000', fontWeight: 'bold' }}>{item.sender}</Text>
<Text>{timeSince(item.time)}</Text>
</View>
</View>
<Text style={{ paddingTop: 4 }}>{item.body}</Text>
<Divider style={{ backgroundColor: '#e7e5e5', height: 2, marginTop: 5, marginBottom: 5 }} />
</>
)}
/>
);
}
};
return (
<View style={{ margin: 5 }} >
{console.log("DEBUG: isLoading = " + isLoading)}
{console.log("DEBUG: data = " + JSON.stringify(data))}
{renderMessagesFlatList(data)}
</View>
);
};
由于这两行代码,FCM会被反复更新,从而导致反模式的循环
setRefreshPage(Math.random() * 100); //<-- You are updating the state refreshPage
}, [refreshPage]); // <--- You use refreshPage as a dependency means useEffect will be called. And then you will setRefreshPage again
setRefreshPage(Math.random()*100)//谢谢你的快速回复!当应用程序在前台收到FCM消息时,我正在使用状态刷新页面触发主屏幕()的刷新,以更新扁平列表组件以包含最新消息。我用更多的代码扩展了原来的问题,显示了更广泛的背景。如果我删除refreshPage依赖项,那么FlatList在初始加载时会呈现良好状态,但在收到新消息时不会升级。谢谢。您不需要触发刷新,因为它是一个侦听器
,它将在每次消息传递()时触发。在消息
,您只需要在侦听器中设置数据
来更新数据,并在flatlist组件中使用extraData={data}在有新数据时触发组件刷新。。
setRefreshPage(Math.random() * 100); //<-- You are updating the state refreshPage
}, [refreshPage]); // <--- You use refreshPage as a dependency means useEffect will be called. And then you will setRefreshPage again