gpt4 book ai didi

javascript - 何时通过 API 调用在 React 中滚动IntoView

转载 作者:行者123 更新时间:2023-11-28 03:41:20 24 4
gpt4 key购买 nike

所以我有一个 React 应用程序,我想滚动到 div 的底部。

   componentDidMount() {
this.pullMessages();
this.scrollToBottom();
}

pullMessages() {
var api = new API(this.props.keycloak);
var merchant_id = this.props.location.pathname.substr(this.props.location.pathname.lastIndexOf('/') + 1);
api.get("merchantMessages", { "repl_str": merchant_id }).then(
response => this.loadMessages(response.data)
).catch(function (error) {
console.log(error);
})
}

loadMessages(data) {
var count = 0;

var messagevals = [];

data.reverse().forEach(function (obj) {
messagevals.push(generateMessage(obj, count, {}));
count++;
});

this.setState({ messages: messagevals });

this.setState({ isLoading: false });

}

scrollToBottom = () => {
// Using this method because the reference didn't work
var bottomele = document.getElementById("bottom-scroll");
if (bottomele !== null) {
bottomele.scrollIntoView();
}
}

render() {

if (this.state.isLoading) {

return (<Loading />)
}
else {
return (

<div>
<div id="messages-container">
<div id="messages">
{ this.state.messages.map((message, index) =>
<div className={ "message " + message.position} key={index}>{message.text}</div>
}
<div className="bottom-scroll" id="bottom-scroll" ref={(el)=> { this.messagesEndRef = el; }}>
</div>
</div>
</div>
</div>
....

它是通过 API 调用填充的(并且会显示加载模式,直到此 API 调用填充状态数组为止)

我的问题是,一旦消息 div 填充完毕,我想滚动到底部。

我的问题是,我的滚动到底部代码似乎是在填充消息之前执行的,因此不会发生滚动。

如何确保仅在填充和呈现消息时滚动?我考虑过将其放入 componentDidUpdate() 中,但问题是我只想在第一次加载时发生此滚动操作,然后在消息发送时发生。

最佳答案

考虑对您的组件进行以下更改:

  • 避免通过查询/getElementById 与 DOM 交互,而是使用元素引用。您通常希望通过 React.createRef()
  • 在组件构造函数中创建引用
  • 要实现所需的滚动行为,请考虑控制“拥有滚动条”的“messages-container”元素,而不是滚动到“messages-container”末尾的占位符元素(即“bottom-scroll”) )
  • 在数据加载后调用 scrollToBottom(),以考虑数据请求的异步性质(即,在收到响应后调用 scrollToBottom()轴)。对于您的代码,调用 scrollToBottom() 的好地方是 loadMessages()
  • 在调用滚动行为之前,确保 UI 中存在更新的数据。您可以通过在 setState() 的回调中调用 scrollToBottom() 来确保数据存在(即当 messages 状态数据更新时)

在代码中,这些更改可以按如下方式实现:

constructor(props) {
super(props);

/*
Create ref to messages-container in constructor
*/
this.containerRef = React.createRef();
}

componentDidMount() {
this.pullMessages();

/* Remove this, we'll instead do this in loadMessages()
this.scrollToBottom();
*/
}

loadMessages(data) {
var count = 0;
var messagevals = [];
data.reverse().forEach(function (obj) {
messagevals.push(generateMessage(obj, count, {}));
count++;
});

/* After updating the message list with loaded data, cause the
messages-container to scroll to bottom. We do this via a call back
passed to setState() for this state update */
this.setState({ messages: messagevals, isLoading : false }, () => {

this.scrollToBottom()
});
}

scrollToBottom = () => {

const containerElement = this.containerRef.current;

if(containerElement) {
/* If container element exists, then scroll to bottom of
container */
containerElement.scrollTop = containerElement.scrollHeight;
}
}

render() {

if (this.state.isLoading) {
return (<Loading />)
}
else {
return (<div>
{/* Add ref here */ }
<div id="messages-container" ref={this.containerRef}>
<div id="messages">
{ this.state.messages.map((message, index) =>
<div className={ "message " + message.position}
key={index}>{message.text}</div>
}
{/*
This can go:
<div className="bottom-scroll"
id="bottom-scroll"
ref={(el)=> { this.messagesEndRef = el; }}>
</div>
*/}
</div>
</div>
</div>)
}
}

希望有帮助!

关于javascript - 何时通过 API 调用在 React 中滚动IntoView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57281187/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com