Reputation: 19341
I am creating application like chat. I want to start scrolling from bottom. (I know how to scroll bottom after displaying message) But, I don't want to force scroll.
import React, { useEffect, useRef } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const Messages = ({ messages }) => {
const messagesEndRef = useRef(null);
const scrollToBottom = () => {
messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
};
useEffect(scrollToBottom, [messages]);
return (
<div className="messagesWrapper">
{messages.map(message => (
<span key={message}>{message}</span>
))}
<div ref={messagesEndRef} />
</div>
);
};
function App() {
const allMessage = ['Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut scelerisque consectetur nibh, sed dictum ligula. Maecenas vitae lacus eget est fermentum sagittis. Nullam vehicula quam felis, porttitor lobortis metus euismod at. Nulla risus sapien, ultricies sed feugiat quis, molestie sit amet erat. Aliquam in lacus ut diam maximus viverra ac eu nibh. Praesent feugiat quis nulla posuere sagittis. Vestibulum nulla magna, ornare et lorem sed, blandit ornare nibh. Morbi ac metus quis dui ullamcorper dictum. Ut scelerisque dignissim quam nec semper. Aliquam ut euismod ligula, sit amet congue sapien. Pellentesque mattis accumsan elit, ac elementum est venenatis ut. Donec vehicula leo id odio tincidunt tempor. Duis eget tempor augue, eu vehicula neque. Praesent vitae mi et nisl sodales faucibus aliquet ut nunc.', 'Curabitur id tincidunt purus. Nam lectus odio, efficitur vel ornare a, commodo vitae mauris. Donec in tincidunt lectus. Maecenas tortor massa, mattis congue sollicitudin eu, maximus et velit. Morbi purus risus, vehicula quis dolor at, tempus pellentesque enim. Mauris tempus quam nulla, eu faucibus nisi hendrerit quis. Duis eu sodales nulla. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse dignissim mattis accumsan. Integer neque mauris, commodo at lorem sit amet, pretium viverra nulla. Aenean eget tincidunt velit, sit amet placerat magna.']
return (
<div className="App">
<Messages messages={allMessage} />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Here, you see that It scroll to bottom. I want to start from bottom.
Working Example: https://codesandbox.io/s/scrolltobottomexample-forked-d8ot6?file=/src/index.js
Upvotes: 0
Views: 396
Reputation: 2008
You can set the scroll of div usingscrollTop
property for the wrapper div messagesWrapper
so that on every render, position will be set to bottom.
Reason why I have updated the reference is, static height is defined on wrapper and the scrollHeight
will return 0 for the div you are referencing.
Update your reference to the wrapper div and set the scrollTop value:
const scrollToBottom = () => {
// set the scroll top
if(messagesEndRef.current) {
messagesEndRef.current.scrollTop = messagesEndRef.current.scrollHeight;
}
};
useEffect(scrollToBottom, [messages]);
// Update your reference
return (
<div className="messagesWrapper" ref={messagesEndRef}>
{messages.map(message => (
<span key={message}>{message}</span>
))}
</div>
);
Same behavior can be achieved with Ref Callback
.
const scrollToBottom = (ref) => {
if(ref) {
ref.scrollTop = ref.scrollHeight;
}
}
// Update your reference
return (
<div className="messagesWrapper" ref={scrollToBottom}>
{messages.map(message => (
<span key={message}>{message}</span>
))}
</div>
);
Upvotes: 3