我想建立一个聊天系统,并自动滚动到底部时,进入窗口,当新的消息进来。如何在React中自动滚动到容器底部?
当前回答
为了向下滚动到页面底部,首先我们必须选择位于页面底部的id。然后我们就可以使用文档了。getElementById选择id并使用scrollIntoView()向下滚动。请参考以下代码。
scrollToBottom= async ()=>{
document.getElementById('bottomID').scrollIntoView();
}
其他回答
我推荐的最简单和最好的方法是。
我的ReactJS版本:16.12.0
对于类组件
render()函数内的HTML结构
render()
return(
<body>
<div ref="messageList">
<div>Message 1</div>
<div>Message 2</div>
<div>Message 3</div>
</div>
</body>
)
)
scrollToBottom()函数,该函数将获取元素的引用。 并根据scrollIntoView()函数滚动。
scrollToBottom = () => {
const { messageList } = this.refs;
messageList.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"});
}
并在componentDidMount()和componentDidUpdate()中调用上述函数
对于功能组件(挂钩)
导入useRef()和useEffect()
import { useEffect, useRef } from 'react'
在导出函数中,(与调用useState()相同)
const messageRef = useRef();
让我们假设页面加载时你必须滚动,
useEffect(() => {
if (messageRef.current) {
messageRef.current.scrollIntoView(
{
behavior: 'smooth',
block: 'end',
inline: 'nearest'
})
}
})
或者,如果你想让它在执行动作时触发,
useEffect(() => {
if (messageRef.current) {
messageRef.current.scrollIntoView(
{
behavior: 'smooth',
block: 'end',
inline: 'nearest'
})
}
},
[stateVariable])
最后是HTML结构
return(
<body>
<div ref={messageRef}> // <= The only different is we are calling a variable here
<div>Message 1</div>
<div>Message 2</div>
<div>Message 3</div>
</div>
</body>
)
有关Element.scrollIntoView()的更多解释,请访问developer.mozilla.org
更详细的解释在回调参考访问reactjs.org
我在mweb/web中遇到过这个问题。所有的解决方案是很好的在这个页面,但所有的解决方案是不工作,而使用android chrome浏览器。 所以对于mweb和web,我得到了一些小的解决方案。
import { createRef, useEffect } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'redux/store';
import Message from '../Message/Message';
import styles from './MessageList.module.scss';
const MessageList = () => {
const messagesEndRef: any = createRef();
const { messages } = useSelector((state: AppState) => state?.video);
const scrollToBottom = () => {
//this is not working in mWeb
// messagesEndRef.current.scrollIntoView({
// behavior: 'smooth',
// block: 'end',
// inline: 'nearest',
// });
const scroll =
messagesEndRef.current.scrollHeight -
messagesEndRef.current.clientHeight;
messagesEndRef.current.scrollTo(0, scroll);
};
useEffect(() => {
if (messages.length > 3) {
scrollToBottom();
}
}, [messages]);
return (
<section className={styles.footerTopSection} ref={messagesEndRef} >
{messages?.map((message: any) => (
<Message key={message.id} {...message} />
))}
</section>
);
};
export default MessageList;
感谢@enlitement
我们应该避免使用findDOMNode, 我们可以使用引用来跟踪组件
render() {
...
return (
<div>
<div
className="MessageList"
ref={(div) => {
this.messageList = div;
}}
>
{ messageListContent }
</div>
</div>
);
}
scrollToBottom() {
const scrollHeight = this.messageList.scrollHeight;
const height = this.messageList.clientHeight;
const maxScrollTop = scrollHeight - height;
this.messageList.scrollTop = maxScrollTop > 0 ? maxScrollTop : 0;
}
componentDidUpdate() {
this.scrollToBottom();
}
参考:
https://facebook.github.io/react/docs/react-dom.html#finddomnode https://www.pubnub.com/blog/2016-06-28-reactjs-chat-app-infinite-scroll-history-using-redux/
不使用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} />;
}
使用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-router中以编程方式更新查询参数?
- 对象作为React子对象无效。如果要呈现子元素的集合,请使用数组
- Redux @connect装饰器中的“@”(at符号)是什么?
- 如何有条件元素和保持干燥与Facebook React的JSX?
- “你正在运行create-react-app 4.0.3,它落后于最新版本(5.0.0)”
- 道具更新状态在React Form中发生变化
- 在setInterval中使用React状态钩子时状态不更新
- 无法访问React实例(此)内部事件处理程序
- 如何滚动到底部的反应?
- 什么是React受控组件和不受控组件?
- npm犯错!代码UNABLE_TO_GET_ISSUER_CERT_LOCALLY
- 反应-显示加载屏幕,而DOM是渲染?
- 如何解决“不能在模块外使用导入语句”在开玩笑
- 是否有可能在react渲染函数中返回空?
- 使用Redux而不是Flux的缺点是什么