I've built a chat application and I'm using a useEffect
to listen to messages.length
, in order to scroll down to bottom upon an arrival of a new message - an increment
in messages.length
.
However, there's also the case where I delete a message, a decrement
in messages.length
. Meaning, I get scrolled down to bottom upon deletion too, and I would like to avoid that kind of behavior. The messages are stored within my redux store and accessible as a prop.
Is there a way for the useEffect
to listen only on an increment?
Is there a way to have access to the messages' previous state?
Or is storing a prevLength
variable unavoidable?
Here is the part of my code that needs revising:
// Scroll to bottom upon new message:
useEffect(() => {
scrollDown();
}, [messages.length]);
This is the entire code:
import { useState, useEffect} from 'react';
//Components:
import ChatBubble from './ChatBubble';
import ScrollButton from './ScrollButton';
export default function MessagesBoard({ messages }) {
//useState:
const [showScrollButton, setShowScrollButton] = useState(false);
//Event: Scroll to bottom upon new message
useEffect(() => {
scrollDown();
}, [messages.length]);
const scrollDown = () => {
....
};
return (
<div className='chatMessagesBlock'>
<div className='messagesCanvas'>
{messages.map((chatMessage) => {
return (
<ChatBubble
key={msgID}
msgID={msgID}
sender={sender}
msgContent={msgContent}
/>
);
})}
</div>
<ScrollButton
showScrollButton={showScrollButton}
scrollDown={scrollDown}
/>
</div>
);
}
You could keep track of the previous length in a useRef
:
const prevLength = useRef(0);
useEffect(() => {
if (prevLength.current < message.length) {
scrollDown();
}
prevLength.current = messages.length;
}, [messages.length]);