我在聊天中看到了一个非常奇怪的行为。聊天室打开后,只有当聊天室中有图像时,滚动条才会向下移动。当只有文本时,它会一直向下。此外,如果我关闭聊天并再次打开,无论内容如何,滚动都会一直向下滚动。然而,如果我刷新页面,滚动将返回到其奇怪的行为。我不明白为什么会发生这种事。这是我的代码:
以下是聊天的开始方式:
startChat () {
document.getElementById("myForm").style.display = "block";
const ref = firebase.firestore().collection('Chats').doc(this.state.uid).collection('Messages');
const query = ref.orderBy('timestamp', 'desc').limit(10)
this.unsubFromMessages = query.onSnapshot((snapshot) => {
if (snapshot.empty) {
console.log('No matching documents.');
firebase.firestore().collection('Chats').doc(this.state.uid).
set({
name: this.state.displayName,
uid: this.state.uid,
email: this.state.email
}).then(console.log("info saved"))
.catch((error) => {
console.log("Error saving info to document: ", error);
});
}
snapshot.docChanges().reverse().forEach((change) => {
if (change.type === 'removed') {
console.log(change.doc.data().content)
}
else if (change.type === 'added') {
this.setState(state => {
const messages = [...state.messages, {id: change.doc.id, body: change.doc.data()}]
return {
messages
}
})
setTimeout( this.scrollToBottom(), 2000)
}
else if (change.type === 'modified') {
const filteredMessages = this.state.messages.filter(message => message.body.allowed === "yes")
this.setState(state => {
const messages = [...filteredMessages, {id: change.doc.id, body: change.doc.data()}]
return {
messages
}
})
setTimeout( this.scrollToBottom(), 2000)
}
});
}, (error) => {console.log(error)});
}
这是滚动功能:
scrollToBottom = () => {
this.myRef.current.scrollIntoView({ behavior: "smooth" });
}
以下是聊天的JSX:
<div className="form-popup" id="myForm">
<form className="form-container" onSubmit={this.chatFormSubmit}>
<h1>Chat</h1>
<label htmlFor="msg"><b>Message</b></label>
<div className="chatArea" id='messages'>
{
this.state.messages.map((message, index) => {
return message.body.uid === this.state.uid && !message.body.imageUrl
?
<p className="message-sent" key={index}>{message.body.content}</p>
:
message.body.uid === this.state.uid && message.body.imageUrl
?
<img src={message.body.imageUrl} className="message-sent" key={index}></img>
:
<p className="message-received" key={index}>{message.body.content}</p>
})
}
<div style={{ float:"left", clear: "both" }}
ref={this.myRef}>
</div>
</div>
如果关闭和向聊天提交消息的功能有任何用处,它们是:
closeForm() {
document.getElementById("myForm").style.display = "none";
this.setState({messages: []})
this.unsubFromMessages();
}
chatFormSubmit(e) {
e.preventDefault();
this.setState({ writeError: null });
firebase.firestore()
.collection('Chats')
.doc(this.state.uid)
.collection('Messages')
.doc()
.set({
docId: this.state.docId,
content: this.chatArea.current.value,
allowed: "yes",
timestamp: new Date(),
uid: this.state.uid,
name: this.state.displayName,
email: this.state.email
}, { merge: true })
.catch((error) => {
this.setState({ writeError: error.message });
})
.then(this.chatArea.current.value = '')
}
再一次,我自己想明白了。而不是调用";this.scrollToBottom(("在setTimeout中,我应该像setTimeout一样简单地传递它(this.crollToBottom,2000(。这就是为什么setTimeout不起作用,滚动中途停止的原因。这要归功于Felix Kling在ReactJS中的评论:setTimeout((不起作用?。