[英]React - Why i assign scrollTop and the element don't get this?
I construct a chat. 我构建了一个聊天。 I want when the component load or I get new message I can to go bottom of the scroll.
我想当组件加载或我收到新消息时我可以去滚动的底部。 Without React, I tried and it's work.
没有React,我尝试了它的工作。 With React, i don't success.
有了React,我没有成功。
Thanks for help 感谢帮助
I already tried in JavaScript and it works, I have already tried in React with refs, like the code in JavaScript. 我已经尝试过使用JavaScript,但是我已经在React中尝试使用refs,就像JavaScript中的代码一样。
const contentMsgElement = document.querySelector("#contentMsg");
contentMsgElement.scrollTop = contentMsgElement.scrollHeight;
import React from 'react';
import ReactDOM from 'react-dom';
import MessageChat from './message/messageChat';
import moment from 'moment';
import MessageDateHeader from './message/messageDateHeader';
class BodyChat extends React.Component
{
constructor(props)
{
super(props);
this.state = {
socket:null,
allMessages:[],
dateNow:""
};
this.messageList = React.createRef();
}
componentDidMount()
{
const {socket,user} = this.props;
this.setState({
socket:socket,
user:user
},this.getLast10Msg);
this.setState({
dateNow:moment.utc().local().format("DD/MM/YY")
});
this.getNewMsg(socket);
}
componentDidUpdate(prevProps,prevState)
{
const prevAll = prevState.allMessages;
const all = this.state.allMessages
if(prevAll.length !== all.length)
{
if(this.messageList.current)
{
const messageList = this.messageList.current;
ReactDOM.findDOMNode(messageList).scrollTop = messageList.scrollHeight;
console.dir(ReactDOM.findDOMNode(messageList));
}
}
}
getLast10Msg = () =>
{
const {socket} = this.state;
socket.on("respGet10Msg",data =>
{
this.setState({
allMessages:data
});
});
}
getNewMsg = socket =>
{
socket.on("respMsg",data =>
{
const newMsg = {
userName:data.userName,
MESSAGE:data.message,
CODE_UTILISATEUR:data.userId,
TIME:data.time,
ID:(data.idMessage) ? "msg_" + data.idMessage : "tpm_" + data.idTpm
};
this.setState({
allMessages:this.state.allMessages.concat(newMsg)
});
this.scrollToBottom();
});
}
scrollToBottom = () =>
{
const contentMsg = this.messageList;
console.log(contentMsg);
contentMsg.scrollTop = contentMsg.scrollHeight;
}
msgDate = (time,displayDate) =>
{
const {dateNow} = this.state;
const date = moment.utc(time).local().format("DD/MM/YY");
const yesterday = moment.utc().local().subtract(1, 'days').format("DD/MM/YY");
const currentDate = displayDate.date;
const respDate = {...displayDate};
if(date !== currentDate)
{
if(dateNow === date)
{
respDate.date = "Aujourd'hui";
}
else if(yesterday === date)
{
respDate.date = "Hier";
}
else
{
respDate.date = date;
}
respDate.display = true;
}
else
{
respDate.display = false;
}
return respDate;
}
render()
{
const {allMessages,user} = this.state;
let displayDate = {date:"",display:false};
if(allMessages.length > 0)
{
const messages = allMessages.map(msg =>
{
const msgChat = <MessageChat
idMessage={msg.ID}
userName={msg.userName}
message={msg.MESSAGE}
userId={msg.CODE_UTILISATEUR}
time={msg.TIME}
currentUser={user.CODE_UTILISATEUR}
key={msg.ID}
/>;
displayDate = this.msgDate(msg.TIME,displayDate);
const msgDate = (displayDate.display) ? <MessageDateHeader date={displayDate.date}/> : "";
return <React.Fragment>
{msgDate}
{msgChat}
</React.Fragment>;
}
);
return <div className="contentMsg" ref={this.messageList}>
{messages}
{("Aujourd'hui" !== displayDate.date) ? <MessageDateHeader date="Aujourd'hui"/> : ""}
</div>;
}
else
{
return <div className="contentMsg">
</div>;
}
}
}
export default BodyChat;
.contentMsg
{
display: grid;
grid-gap: 0.2rem;
overflow-y: auto;
overflow-x: hidden;
}
I except scroll when chat mount or update at the bottom but nothing append! 我除了在聊天安装时滚动或在底部更新但没有任何附加!
@anik islam Shojib @anik islam Shojib
i try and don't work 我试着不工作
componentDidUpdate(prevProps,prevState) { if(this.messageList) { console.log("here"); console.log(this.messageList.offsetTop); window.scrollTo({ top:this.messageList.offsetTop, behavior: "smooth" // Optional, adds animation }) console.log(this.messageList.scrollTop); } }
Put an invisible div
to the bottom of your chat screen. 将一个不可见的
div
放在聊天屏幕的底部。 (Inside contentMsg
.) (Inside
contentMsg
。)
<div style={{display: none}} />
Then, Define a ref
in your constructor: 然后,在构造函数中定义一个
ref
:
this.myRef = React.createRef()
Attach this ref
to your invisible div
: 将此
ref
附加到您的隐形div
:
<div style={{display: none}} ref={el => this.myRef = el} />
Then whenever you want to scroll to bottom (eg componentDidUpdate
), call this function: 然后,只要您想要滚动到底部(例如
componentDidUpdate
),请调用此函数:
this.myRef.scrollIntoView();
i found the solution. 我找到了解决方案。 I don't know why the render is not finish and call the function componentDidUpdate before.
我不知道为什么渲染没有完成并且之前调用了函数componentDidUpdate。 so the first time we say the render had update and it works.
所以我们第一次说渲染有更新,它的工作原理。
I think it's a trick but if someone know a better solution. 我认为这是一个技巧,但如果有人知道更好的解决方案。
componentDidUpdate(prevProps,prevState) { if(this.state.allMessages.length > 0 && prevState.allMessages.length !== this.state.allMessages.length) { this.setState({ changeHeight: true }); } if(this.state.changeHeight && this.state.changeHeight !== prevState.changeHeight) { let height = ReactDOM.findDOMNode(this).scrollHeight; ReactDOM.findDOMNode(this).scrollTop = height; this.setState({ changeHeight: false }); } }
here is scroll code for react. 这里是反应的滚动代码。 this code works for I think will for you too
这段代码适用于我认为也适合你
componentDidUpdate(prevProps,prevState)
{
const prevAll = prevState.allMessages;
const all = this.state.allMessages
if(prevAll.length !== all.length)
{
if(this.messageList.current)
{
window.scrollTo({
top:this.messageList.offsetTop,
behavior: "smooth" // Optional, adds animation
})
console.dir(ReactDOM.findDOMNode(messageList));
}
}
}
you can use ref as like 你可以像使用ref一样
return <div className="contentMsg" ref={(e) => this.messageList= e} >
{messages}
{("Aujourd'hui" !== displayDate.date) ? <MessageDateHeader
date="Aujourd'hui"/> : ""}
</div>;
This is also supposed to work but didn't work for me either 这也应该有效但对我来说也不起作用
ReactDOM.findDOMNode(messageList).scrollTop = messageList.scrollHeight;
can you try one thing only run following section in your componentDidUpdate 你能尝试一下只运行componentDidUpdate中的一节吗?
componentDidUpdate(prevProps,prevState)
{
window.scrollTo({
top:this.messageList.offsetTop,
behavior: "smooth" // Optional, adds animation
})
}
and see if it works, if it does then something wrong with your condition 并查看它是否有效,如果它确实你的病情有问题
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.