我正在创建一个聊天应用,我有一个用于显示所有消息的主屏幕组件。我试图确保每当用户发送或接收一条消息时,该组件就会渲染并更新
Flatlist
以显示最后发送的消息。我使用Firebase实时数据库来监听更新。
我在我的应用程序中使用函数式组件,但我认为我错误地使用了setState,因为它导致我的组件多次重新渲染。
我已经仔细检查了提问的问题,但似乎没有一个与我的问题相关。
这是我的代码。
const AllMessagesScreen = ({ navigation }) => {
const uid = firebase.auth().currentUser.uid;
const [state, setState] = useState({
allMessages: []
});
const { allMessages } = state;
const fsdb = firebase.firestore().collection('Users');
const db = database().ref(`messages/${uid}`); //realtime database
const get = async () => {
try {
await db.on('value', snapshot => {
snapshot.forEach(item => {
const { key: _id } = item;
const { lastMessage } = item.val();
fsdb.doc(_id).get().then((doc => {
const otherUser = doc.data();
const newChat = {
id: _id,
name: otherUser.name,
picture: otherUser.pictures.thumbnailUrl,
lastMessage: lastMessage
};
setState(prevState => ({
allMessages: [...prevState.allMessages, newChat]
}));
})).catch((err) => {
console.log('caught', err)
});
});
});
} catch (err) {
console.log('error caught', err)
};
};
useEffect(() => {
get();
}, []);
return (
<View style={styles.screen}>
<FlatList
data={allMessages}
keyExtractor={item => item.id}
renderItem={({ item }) => (
<View style={{ flex: 1 }}>
<MessageCard
id={item.id}
name={item.name}
image={item.picture}
lastMessageText={item.lastMessage.text}
/>
</View>
)}
/>
</View>
);
}
我也尝试过这样设置状态
setState({ allMessages: [...allMessages, newUser] });
``
The second way only shows the last rendered message and gets rid of the rest.
Any help is really appreciated