reactjs - 如何使用 Reactjs 正确实现 div 消息的 scrollHeight 或 scrollTop
问题描述
我正在尝试在 Reactjs 中实现聊天消息。聊天消息被正确附加并且工作正常。
这是我的问题:聊天消息到达底部时不会向上滚动。
我正在考虑在消息到达底部时实现诸如聊天 div 自动滚动之类的功能。
scrollToBottom() {
chat_messages.scrollTop = chat_messages.scrollHeight;
}
有什么解决方法吗?
这是代码:
<!DOCTYPE html>
<html>
<head>
<style>
.chat_container{
background:blue;
height:40%;
max-height:40%;
width: 60%;
max-width: 60%;
overflow-y: auto;
}
.chat_message{
background:green;
color:white;
padding:10px;
border:none;
}
.myFooter{
bottom:0px;
position:fixed;
background:red;
height:10%;
max-height:10%;
width: 60%;
max-width: 60%;
}
</style>
</head>
<body>
<script src="build/react.min.js"></script>
<script src="build/react-dom.min.js"></script>
<script src="build/browser.min.js"></script>
<script src="build/jquery.min.js"></script>
<div id="app"></div>
<script type="text/babel">
class Application extends React.Component {
//function Application() {
constructor(props) {
super(props);
const sender = 'John';
this.state = {
message: '',
value: '',
sname: sender,
date: new Date(),
messages: []
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({message: event.target.value});
}
handleSubmit(event) {
// alert('A name was submitted: ' + this.state.message);
event.preventDefault();
const data = {'message': this.state.message}
this.setState({
messages : this.state.messages.concat([data])
});
//$(".chat_container").animate({ scrollTop: 20000000 }, "slow");
this.scrollToBottom();
}
scrollToBottom() {
chat_messages.scrollTop = chat_messages.scrollHeight;
}
componentDidMount() {
// fetch content axio or ajax
}
render() {
return (
<div>
<div className="chat_container">
<h2>Welcome to Chat: Time is: {this.state.date.toLocaleTimeString()}</h2>
{this.state.messages.map((m, e) => (
<div key={e}>
<div className="chat_message">chat: {m.message} ---{this.state.date.toLocaleTimeString()}</div>
</div>
))}
</div>
<div className="myFooter">
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.message} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
</div>
</div>
);
}
}
ReactDOM.render(<Application />, document.getElementById('app'));
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
</body>
</html>
解决方案
我得到了你的例子:
bottomRef.current.scrollIntoView({ behavior: "smooth" });
这是完整的代码;我很荣幸将它转换为一个功能性的 React 组件并使用了 useRef 钩子(滚动发生在消息状态更新的任何时候):
import React, { useState, useRef, useEffect } from "react";
import "./styles.css";
export default function App(props) {
const [message, setMessage] = useState("");
const [messages, setMessages] = useState([]);
const currentDate = new Date();
const bottomRef = useRef();
useEffect(() => {
// fetch content axio or ajax
}, []);
useEffect(() => {
bottomRef.current.scrollIntoView({ behavior: "smooth" });
}, [messages]);
function handleChange(event) {
setMessage(event.target.value);
}
function handleSubmit(event) {
// alert('A name was submitted: ' + this.state.message);
event.preventDefault();
const newMessages = messages;
const data = { message: message, date: new Date() };
setMessages(newMessages.concat([data]));
}
return (
<React.Fragment>
<h2>Welcome to Chat: Time is: {currentDate.toLocaleTimeString()}</h2>
<div className="chat_container">
{messages.map((m, e) => (
<div key={e}>
<div className="chat_message">
chat: {m.message} ---{m.date.toLocaleTimeString()}
</div>
</div>
))}
<div id="bottom-reference" ref={bottomRef} />
</div>
<div className="myFooter">
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" value={message} onChange={handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
</div>
</React.Fragment>
);
}
我使用这些样式来测试滚动:
.chat_container {
height: 200px;
overflow: scroll;
}
推荐阅读
- syncfusion - Sfgrid 列标题不与列对齐
- php - 10.4.11-MariaDB (MySql) 和 PHP 7.2.29 UTF-8 编码的问题
- mysql - 替代使用在 mysql 中
- elasticsearch - 带有必须(和)应该(或)不产生预期结果的 Elasticsearch 查询
- tensorflow - 如何冻结一个模型的子模型,而不影响其他模型?
- javascript - 每次特定用户在现有网站上发送消息时播放声音/通知
- python - 元组上的哈希输出不一致
- pandas - pandas to_csv 为字符串“test123”hello world 创建问题
- mysql - mysql docker无法从外部容器连接
- json - 使用 XML 对象读取 XML 文件会导致缺少条目