Cloyd Abad
Cloyd Abad

Reputation: 737

Reactjs, How to make scroll stay at current position when scrollable div extends

I'm trying to build a react Chat app and I was going to use the infinite scroll but it doesn't work the way I wanted it to. So I built one myself. I used useref to determine the height and if it reaches to the top it will add more chats. kinda like fb messenger's chat. The problem now is that when I add more chats, once it reaches the top, the scroll bar will continue to go up and not stick in place unlike how react-infinite scroll works. enter image description here

May I know how I can go through this? Here is my code. for the scroll:

const onScroll = () => {
        if (topDiv.current) {
            const { scrollTop, scrollHeight, clientHeight } = topDiv.current;
            if(scrollTop === 0){
                props.fecthMoreChat()
            }
        }
    };
return(
     <div id='scrollableDiv' ref={topDiv} onScroll={()=> onScroll()} style={{height:'100%', padding:'20px', display:'flex', flexDirection:'column', backgroundColor:'#efefef', overflowY:'scroll'}}>
          {/* <div style={{visibility:'hidden'}} ref={topDiv}></div> */}
             {currentChat.map((chat, index)=>{
                 return(
                     <div key={index} style={{textAlign:chat.sender===username?'right':'left'}}>
                         {chat.message}
                     </div>
                 )
             })}
         <div style={{visibility:'hidden'}} ref={botMsg}></div>
     </div>
    )

Upvotes: 2

Views: 2431

Answers (1)

Cloyd Abad
Cloyd Abad

Reputation: 737

So the answer was actually pretty simple. I just took the current scroll height, saved it in a variable, then waited for the re-render and took the new scroll height. Basically, just subtract the old scroll height with the new scroll height and use that number to set scroll by using scrollTo(). Here is the code:

const onScroll = async () => {
        if (chatDiv.current) {
            const { scrollTop, scrollHeight, clientHeight } = chatDiv.current;
            if(scrollTop === 0){
                const pastScroll = scrollHeight
                await props.fecthMoreChat()
                const currentScroll = (await chatDiv.current.scrollHeight-pastScroll) 
                await chatDiv.current.scrollTo(0, currentScroll)
            }
        }
    };

Upvotes: 4

Related Questions