Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scroll to bottom of an overflowing div in React

I have a ul with a max-height and overflow-y: auto.

When the user enters enough li elements, the ul starts to scroll, but I want the last li with the form in it to always be present and viewable to the user.

I've tried implementing a scrollToBottom function that looks like this:

scrollToBottom() {     this.formLi.scrollIntoView({ behavior: 'smooth' }); } 

But that just makes the ul jump to the top of the screen and show the li with the form in it as the only visible thing.

Is there a better way to accomplish this? Answers I find tend to be a bit older and use ReactDOM. Thanks!

CSS:

.prompt-box .options-holder {     list-style: none;     padding: 0;     width: 95%;     margin: 12px auto;     max-height: 600px;     overflow-y: auto; } 

HTML:

<ul className='options-holder'>     {         this.state.items.map((item, index) => (             <li key={item.id} className={`option ${index === 0 ? 'first' : ''}`}>                 <div className='circle' onClick={this.removeItem} />                  <p className='item-text'>{ item.text }</p>             </li>         ))     }      <li key={0} className={`option form ${this.state.items.length === 0 ? 'only' : ''}`} ref={el => (this.formLi = el)}>         <div className='circle form' />          <form className='new-item-form' onSubmit={this.handleSubmit}>             <input                  autoFocus                  className='new-item-input'                  placeholder='Type something and press return...'                  onChange={this.handleChange}                  value={this.state.text}                 ref={(input) => (this.formInput = input)} />         </form>     </li>  </ul> 
like image 993
Zack Shapiro Avatar asked Aug 16 '17 17:08

Zack Shapiro


People also ask

How do I scroll to the bottom of a div?

Use element. scroll() to Scroll to Bottom of Div in JavaScript. You can use element.

How do you get scroll bottom position in React?

To detect when a user scrolls to bottom of div with React, we can check if the sum of the scrollTop and clientHeight properties of a scrollable element is equal to the scrollHeight property of the same element. We call the useRef hook to create a ref and we assign the returned ref to the inner div, which is scrollable.

How do you handle scrolling in React?

To handle the onScroll event in React: Set the onScroll prop on an element or add an event listener on the window object. Provide an event handler function. Access relevant properties on the event or window objects.


2 Answers

I have a container that fills the height of the page. This container has display flex and flex direction column. Then I have a Messages component which is a ul with one li per message plus a special AlwaysScrollToBottom component as the last child that, with the help of useEffect, scrolls to the bottom of the list.

const AlwaysScrollToBottom = () => {   const elementRef = useRef();   useEffect(() => elementRef.current.scrollIntoView());   return <div ref={elementRef} />; };  const Messages = ({ items }) => (   <ul>     {items.map(({id, text}) => <li key={id}>{text}</li>)}     <AlwaysScrollToBottom />   </ul> )  const App = () => (   <div className="container">     <Messages items={[...]}>     <MessageComposer />   </div> )  

The CSS is

.container {   display: flex;   height: 100vh;   flex-direction: column; }  ul {   flex-grow: 1;   overflow-y: auto; } 

MessageComposer has been omitted for brevity, it contains the form, the input field, etc. to send messages.

like image 57
Jonathan Morales Vélez Avatar answered Sep 23 '22 02:09

Jonathan Morales Vélez


Use react-scroll library. However you will have to explicitly set ID of your ul.

import { animateScroll } from "react-scroll";  scrollToBottom() {     animateScroll.scrollToBottom({       containerId: "options-holder"     }); } 

You can call scrollToBottom on setState callback.

For example

this.setState({ items: newItems}, this.scrollToBottom); 

Or by using setTimeout.

Or you can even set Element from react-scroll and scroll to a certain li.

like image 36
emil Avatar answered Sep 22 '22 02:09

emil