我想建立一个聊天系统,并自动滚动到底部时,进入窗口,当新的消息进来。如何在React中自动滚动到容器底部?
当前回答
在上面的答案中,scrollIntoView(…)方法有两个主要问题:
it's semantically incorrect, as it causes the entire page to scroll if your parent element is scrolled outside the window boundaries. The browser literally scrolls anything it needs to in getting the element visible. in a functional component using useEffect(), you get unreliable results, at least in Chrome 96.0.4665.45. useEffect() gets called too soon on page reload and the scroll doesn't happen. Delaying scrollIntoView with setTimeout(..., 0) fixes it for page reload, but not first load in a fresh tab, at least for me. shrugs
这是我一直在使用的解决方案,它很可靠,而且更兼容旧的浏览器:
function Chat() {
const chatParent = useRef<HTMLDivElement(null);
useEffect(() => {
const domNode = chatParent.current;
if (domNode) {
domNode.scrollTop = domNode.scrollHeight;
}
})
return (
<div ref={chatParent}>
...
</div>
)
}
其他回答
我不能得到以下任何答案的工作,但简单的js为我做的伎俩:
window.scrollTo({
top: document.body.scrollHeight,
left: 0,
behavior: 'smooth'
});
这对我很有用
messagesEndRef.current.scrollTop = messagesEndRef.current.scrollHeight
const messagesEndRef = useRef();使用
const scrollingBottom = () => {
const e = ref;
e.current?.scrollIntoView({
behavior: "smooth",
block: "center",
inline: "start",
});
};
useEffect(() => {
scrollingBottom();
});
<span ref={ref}>{item.body.content}</span>
工作的例子:
您可以使用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
谢谢你的回答,但我认为我们可以做得更好, 对于滚动到底部,我们应该使用这个:
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>
);
}
推荐文章
- 如何滚动到底部的反应?
- 什么是React受控组件和不受控组件?
- npm犯错!代码UNABLE_TO_GET_ISSUER_CERT_LOCALLY
- 反应-显示加载屏幕,而DOM是渲染?
- 如何解决“不能在模块外使用导入语句”在开玩笑
- 是否有可能在react渲染函数中返回空?
- 使用Redux而不是Flux的缺点是什么
- 反应:为什么当道具改变时子组件不更新
- React vs ReactDOM?
- Axios -删除请求与请求体和头?
- “react-scripts”不被视为内部或外部命令
- 如何从状态数组中删除一个项目?
- 是否可以用if…else…语句在React渲染函数?
- 如何设置默认的复选框ReactJS?
- 反应。类型无效——期望为字符串