我想建立一个聊天系统,并自动滚动到底部时,进入窗口,当新的消息进来。如何在React中自动滚动到容器底部?
当前回答
谢谢你的回答,但我认为我们可以做得更好, 对于滚动到底部,我们应该使用这个:
scrollToBottom = () => {
this.messagesEnd.scrollIntoView({ behavior: "smooth", block: "end", inline: "nearest" });
}
但如果你想滚动顶部,你应该使用这个:
scrollToTop = () => {
this.messagesEnd.scrollIntoView({ behavior: "smooth", block: "start", inline: "nearest" });
}
这些代码很常见:
componentDidMount() {
this.scrollToBottom();
}
componentDidUpdate() {
this.scrollToBottom();
}
render () {
return (
<div>
<div className="MessageContainer" >
<div className="MessagesList">
{this.renderMessages()}
</div>
<div style={{ float:"left", clear: "both" }}
ref={(el) => { this.messagesEnd = el; }}>
</div>
</div>
</div>
);
}
其他回答
不使用findDOMNode
带有ref的类组件
class MyComponent extends Component {
componentDidMount() {
this.scrollToBottom();
}
componentDidUpdate() {
this.scrollToBottom();
}
scrollToBottom() {
this.el.scrollIntoView({ behavior: 'smooth' });
}
render() {
return <div ref={el => { this.el = el; }} />
}
}
带钩子的功能组件:
import React, { useRef, useEffect } from 'react';
const MyComponent = () => {
const divRef = useRef(null);
useEffect(() => {
divRef.current.scrollIntoView({ behavior: 'smooth' });
});
return <div ref={divRef} />;
}
Reference your messages container. <div ref={(el) => { this.messagesContainer = el; }}> YOUR MESSAGES </div> Find your messages container and make its scrollTop attribute equal scrollHeight: scrollToBottom = () => { const messagesContainer = ReactDOM.findDOMNode(this.messagesContainer); messagesContainer.scrollTop = messagesContainer.scrollHeight; }; Evoke above method on componentDidMount and componentDidUpdate. componentDidMount() { this.scrollToBottom(); } componentDidUpdate() { this.scrollToBottom(); }
这是我如何在我的代码中使用这个:
export default class StoryView extends Component {
constructor(props) {
super(props);
this.scrollToBottom = this.scrollToBottom.bind(this);
}
scrollToBottom = () => {
const messagesContainer = ReactDOM.findDOMNode(this.messagesContainer);
messagesContainer.scrollTop = messagesContainer.scrollHeight;
};
componentDidMount() {
this.scrollToBottom();
}
componentDidUpdate() {
this.scrollToBottom();
}
render() {
return (
<div>
<Grid className="storyView">
<Row>
<div className="codeView">
<Col md={8} mdOffset={2}>
<div ref={(el) => { this.messagesContainer = el; }}
className="chat">
{
this.props.messages.map(function (message, i) {
return (
<div key={i}>
<div className="bubble" >
{message.body}
</div>
</div>
);
}, this)
}
</div>
</Col>
</div>
</Row>
</Grid>
</div>
);
}
}
工作的例子:
您可以使用DOM scrollIntoView方法使组件在视图中可见。
为此,在呈现组件时,只需使用ref属性为DOM元素提供一个引用ID。然后在componentDidMount生命周期上使用scrollIntoView方法。我只是把这个解决方案的工作示例代码。以下是每次接收到消息时的组件呈现。您应该编写代码/方法来呈现该组件。
class ChatMessage extends Component {
scrollToBottom = (ref) => {
this.refs[ref].scrollIntoView({ behavior: "smooth" });
}
componentDidMount() {
this.scrollToBottom(this.props.message.MessageId);
}
render() {
return(
<div ref={this.props.message.MessageId}>
<div>Message content here...</div>
</div>
);
}
}
这里this.props.message.MessageId是作为道具传递的特定聊天消息的唯一ID
完整版(Typescript):
import * as React from React 导出类DivWithScrollHere扩展React。组件<any, any> { loading:any = React.createRef(); componentDidMount () { this.loading.scrollIntoView(假); } 呈现(){ 回报( <div ref={e =>{这个。装载= e;}}> <LoadingTile /> </div> . txt ) } }
使用React.createRef ()
class MessageBox extends Component {
constructor(props) {
super(props)
this.boxRef = React.createRef()
}
scrollToBottom = () => {
this.boxRef.current.scrollTop = this.boxRef.current.scrollHeight
}
componentDidUpdate = () => {
this.scrollToBottom()
}
render() {
return (
<div ref={this.boxRef}></div>
)
}
}
推荐文章
- 如何配置历史记录?
- React钩子:从回调中访问最新状态
- React-Native:应用程序未注册错误
- ReactJS和公共文件夹中的图像
- React: 'Redirect'没有从' React -router-dom'中导出
- 如何在React中使用钩子强制组件重新渲染?
- React组件中使用TypeScript的默认属性值
- 反应钩子-正确的方式清除超时和间隔
- 在React.js中正确的img路径
- 在React.js中更新组件onScroll的样式
- onClick ReactJS调用多个函数
- 为什么React 16中的Fragments比容器div更好?
- 如何在ReactJS中验证嵌套对象的PropTypes ?
- 如何在ReactJS中从“外部”访问组件方法?
- 'React'指的是一个UMD全局,但当前文件是一个模块