React Native Gifted Chat + Firestore 没有正确显示消息?
React Native Gifted Chat + Firestore not showing messages correctly?
我正在尝试在我的 React 本机应用程序中创建聊天功能。我正在使用 react-native-gifted-chat 并将消息保存在 firestore 中。这是正在发生的行为:
当我发送消息时,所有消息都重新呈现,其中一些是重复的,如您所见,到目前为止我只发送了 3 条消息,但所有这些重复的消息让我想知道为什么整个事情都重新呈现-渲染以及为什么在重新渲染时会出现重复。
代码:
class Chat extends React.Component {
constructor(props) {
super(props)
this.state = {
messages: [],
currentUser: null,
isLoading: true,
messageID: ""
}
}
//---------------------------------------------------------------
async componentDidMount (){
// get user info from firestore
let userUID = Firebase.auth().currentUser.uid
await Firebase.firestore().collection("users").doc(userUID).get()
.then(doc => {
data = doc.data()
this.setState({
currentUser: {
name: data.username,
avatar: data.profilePic,
_id: doc.id,
},
})
})
const messages = []
await Firebase.firestore().collection("chat")
.orderBy("createdAt", "desc")
.limit(50)
.onSnapshot(querySnapshot => {
querySnapshot.forEach((res) => {
const {
user,
text,
createdAt,
} = res.data();
messages.push({
key: res._id,
user,
text,
createdAt,
});
})
this.setState({
messages,
isLoading: false,
});
})
}
//Load 50 more messages when the user scrolls
//
//Add a message to firestore
onSend = async(message) => {
await Firebase.firestore().collection("chat")
.add({
user: {
_id: this.state.currentUser._id,
name: this.state.currentUser.name,
avatar: this.state.currentUser.avatar,
},
})
.then(ref => this.setState({messageID: ref.id}))
await Firebase.firestore().collection("chat")
.doc(this.state.messageID)
.set({
_id: this.state.messageID,
text: message[0].text,
createdAt: message[0].createdAt
}, { merge: true })
}
render() {
if(this.state.isLoading){
return(
<View style = {{backgroundColor: '#000000', flex: 1}}>
<ActivityIndicator size="large" color="#9E9E9E"/>
</View>
)
}
return (
<View style={{backgroundColor: '#000000', flex: 1}}>
<GiftedChat
showUserAvatar={true}
renderUsernameOnMessage={true}
messages={this.state.messages}
onSend={message => this.onSend(message)}
scrollToBottom
/>
</View>
)
}
}
一些注意事项:
- 每次安装组件时,消息数组都会将消息推送到状态数组。
- 组件在我发送消息时挂载,从而重新呈现消息数组
- 每条消息 ID 都是唯一的,由 firebase 使用“添加”生成
告诉我如何解决这个问题!谢谢
重复是因为只有一行
const messages = []
将此行移到侦听器中,i.e.onSnapShot()
await Firebase.firestore().collection("chat")
.orderBy("createdAt", "desc")
.limit(50)
.onSnapshot(querySnapshot => {
const messages = []
// rest of your code which is having forEach loop
});
问题是 messages
对象仅在加载组件时创建一次,并且您仅将元素推送到该对象。
我正在尝试在我的 React 本机应用程序中创建聊天功能。我正在使用 react-native-gifted-chat 并将消息保存在 firestore 中。这是正在发生的行为:
当我发送消息时,所有消息都重新呈现,其中一些是重复的,如您所见,到目前为止我只发送了 3 条消息,但所有这些重复的消息让我想知道为什么整个事情都重新呈现-渲染以及为什么在重新渲染时会出现重复。
代码:
class Chat extends React.Component {
constructor(props) {
super(props)
this.state = {
messages: [],
currentUser: null,
isLoading: true,
messageID: ""
}
}
//---------------------------------------------------------------
async componentDidMount (){
// get user info from firestore
let userUID = Firebase.auth().currentUser.uid
await Firebase.firestore().collection("users").doc(userUID).get()
.then(doc => {
data = doc.data()
this.setState({
currentUser: {
name: data.username,
avatar: data.profilePic,
_id: doc.id,
},
})
})
const messages = []
await Firebase.firestore().collection("chat")
.orderBy("createdAt", "desc")
.limit(50)
.onSnapshot(querySnapshot => {
querySnapshot.forEach((res) => {
const {
user,
text,
createdAt,
} = res.data();
messages.push({
key: res._id,
user,
text,
createdAt,
});
})
this.setState({
messages,
isLoading: false,
});
})
}
//Load 50 more messages when the user scrolls
//
//Add a message to firestore
onSend = async(message) => {
await Firebase.firestore().collection("chat")
.add({
user: {
_id: this.state.currentUser._id,
name: this.state.currentUser.name,
avatar: this.state.currentUser.avatar,
},
})
.then(ref => this.setState({messageID: ref.id}))
await Firebase.firestore().collection("chat")
.doc(this.state.messageID)
.set({
_id: this.state.messageID,
text: message[0].text,
createdAt: message[0].createdAt
}, { merge: true })
}
render() {
if(this.state.isLoading){
return(
<View style = {{backgroundColor: '#000000', flex: 1}}>
<ActivityIndicator size="large" color="#9E9E9E"/>
</View>
)
}
return (
<View style={{backgroundColor: '#000000', flex: 1}}>
<GiftedChat
showUserAvatar={true}
renderUsernameOnMessage={true}
messages={this.state.messages}
onSend={message => this.onSend(message)}
scrollToBottom
/>
</View>
)
}
}
一些注意事项:
- 每次安装组件时,消息数组都会将消息推送到状态数组。
- 组件在我发送消息时挂载,从而重新呈现消息数组
- 每条消息 ID 都是唯一的,由 firebase 使用“添加”生成
告诉我如何解决这个问题!谢谢
重复是因为只有一行
const messages = []
将此行移到侦听器中,i.e.onSnapShot()
await Firebase.firestore().collection("chat")
.orderBy("createdAt", "desc")
.limit(50)
.onSnapshot(querySnapshot => {
const messages = []
// rest of your code which is having forEach loop
});
问题是 messages
对象仅在加载组件时创建一次,并且您仅将元素推送到该对象。