Infinite scroll

React Bootstrap 5 Infinite scroll

This feature adds a scroll event listener (to the window or the component it's attached to if it has the overflow-y property set to scroll) and calls a callback method every time a user reaches an end of a page/container.

Note: Read the API tab to find all available options and advanced customization


Basic example

Scroll down the container below to add more items.

Note: Your element should be scrollable, for example, it should have overflow-y: scroll property like in the example below.

  • Angry
  • Dizzy
  • Flushed
  • Frown
  • Grimace
  • Grin
        
            
          import React, { useState, useRef } from 'react';
          import { MDBInfiniteScroll } from 'mdb-react-ui-kit';
  
          export default function App() {
            const infiniteRef = useRef<HTMLDivElement>(null);

            const [itemIndex, setItemIndex] = useState(0);
            const [renderedIcons, setRenderedIcons] = useState(['Angry', 'Dizzy', 'Flushed', 'Frown', 'Grimace', 'Grin']);

            const icons = ['Sad-Tear', 'Meh-Blank', 'Smile-Wink', 'Tired', 'Surprise', 'Kiss-Beam', 'Laugh-Squint'];

            const handleScroll = () => {
              if (itemIndex > icons.length - 1) {
                return;
              }
          
              setRenderedIcons([...renderedIcons, icons[itemIndex]]);
          
              setItemIndex(itemIndex + 1);
            };

            return (
              <MDBInfiniteScroll
                infiniteScrollRef={infiniteRef}
                className='container list-group'
                style={{ maxHeight: '261px', overflowY: 'scroll' }}
                onInfiniteScroll={handleScroll}
              >
                {renderedIcons.map((icon) => (
                  <li key={icon.toLocaleLowerCase()} className='list-group-item d-flex align-items-center'>
                    <i className={`far fa-${icon.toLowerCase()} fa-3x me-4`}></i>
                    {icon}
                  </li>
                ))}
              </MDBInfiniteScroll>
            );
          }
          
        
    

Direction

Use infiniteDirection property to define the scrolling direction.

Angry Dizzy Flushed Grimace Grin
        
            
          import React, { useState, useRef } from 'react';
          import { MDBInfiniteScroll } from 'mdb-react-ui-kit';
  
          export default function App() {
            const directionRef = useRef<HTMLDivElement>(null);

            const [directionIndex, setDirectionIndex] = useState(0);
            const [directionIcons, setDirectionIcons] = useState(['Angry', 'Dizzy', 'Flushed', 'Frown', 'Grimace', 'Grin']);

            const icons = ['Sad-Tear', 'Meh-Blank', 'Smile-Wink', 'Tired', 'Surprise', 'Kiss-Beam', 'Laugh-Squint'];

            const handleDirectionScroll = () => {
              if (directionIndex > icons.length - 1) {
                return;
              }
          
              setDirectionIcons([...directionIcons, icons[directionIndex]]);
          
              setDirectionIndex(directionIndex + 1);
            };
            
            return (
              <MDBInfiniteScroll
                infiniteDirection='x'
                infiniteScrollRef={directionRef}
                className='py-3 text-center'
                style={{ maxWidth: '1500px', overflowX: 'scroll', whiteSpace: 'nowrap' }}
                onInfiniteScroll={handleDirectionScroll}
              >
                {directionIcons.map((icon) => (
                  <span key={icon.toLocaleLowerCase()} className='mx-5'>
                    <i className={`far fa-${icon.toLocaleLowerCase()} fa-3x me-4`} /> {icon}
                  </span>
                ))}
              </MDBInfiniteScroll>
            );
          }
          
        
    

Spinners and asynchronous data

        
            
          import React, { useState, useRef } from 'react';
          import { MDBInfiniteScroll, MDBSpinner } from 'mdb-react-ui-kit';
  
          export default function App() {
            const asyncRef = useRef<HTMLDivElement>(null);
            const [isSpinnerHidden, setIsSpinnerHidden] = useState(false);
            const [asyncIndex, setAsyncIndex] = useState(0);
            const [asyncImages, setAsyncImages] = useState([
              'https://mdbootstrap.com/img/Photos/Slides/img%20(100).webp',
              'https://mdbootstrap.com/img/Photos/Slides/img%20(105).webp',
              'https://mdbootstrap.com/img/Photos/Slides/img%20(106).webp',
            ]);

            const images = [
              'https://mdbootstrap.com/img/Photos/Slides/img%20(102).webp',
              'https://mdbootstrap.com/img/Photos/Slides/img%20(103).webp',
              'https://mdbootstrap.com/img/Photos/Slides/img%20(104).webp',
              'https://mdbootstrap.com/img/Photos/Slides/img%20(107).webp',
              'https://mdbootstrap.com/img/Photos/Slides/img%20(108).webp',
              'https://mdbootstrap.com/img/Photos/Slides/img%20(109).webp',
              'https://mdbootstrap.com/img/Photos/Slides/img%20(110).webp',
            ];
        

            const handleAsyncScroll = () => {
              if (asyncIndex > images.length - 1) {
                return;
              }
          
              setIsSpinnerHidden(false);
          
              setTimeout(() => {
                setAsyncImages([...asyncImages, images[asyncIndex]]);
          
                setIsSpinnerHidden(true);
                setAsyncIndex(asyncIndex + 1);
              }, 1000);
            };
            
            return (
              <MDBInfiniteScroll
                infiniteScrollRef={asyncRef}
                className='container list-group'
                style={{ maxHeight: '500px', overflowY: 'scroll' }}
                onInfiniteScroll={handleAsyncScroll}
              >
                <div>
                  {asyncImages.map((image, index) => (
                    <img src={image} key={index} className='img-fluid mb-3' />
                  ))}
                </div>

                <div>
                  <MDBSpinner
                    tag='div'
                    role='status'
                    style={{ display: isSpinnerHidden ? 'none' : 'block' }}
                    className='mx-auto'
                  />
                </div>
              </MDBInfiniteScroll>
            );
          }
          
        
    

Window

You can set a window as the parent of MDBInfiniteScroll component by using windowParent property.

        
            
          import React, { useState, useRef } from 'react';
          import { MDBContainer, MDBRow, MDBCol, MDBRipple, MDBBtn, MDBInfiniteScroll } from 'mdb-react-ui-kit';
  
          export default function App() {
            const newImages = [
              {
                first: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/31.webp',
                second: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/23.webp',
              },
              {
                first: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/29.webp',
                second: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/27.webp',
              },
              {
                first: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/25.webp',
                second: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/24.webp',
              },
              {
                first: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/31.webp',
                second: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/32.webp',
              },
            ];
          
            const [imgCounter, setImgCounter] = useState(0);
          
            const [images, setImages] = useState([
              {
                first: 'https://mdbootstrap.com/img/Photos/Others/images/29.webp',
                second: 'https://mdbootstrap.com/img/Photos/Others/images/27.webp',
              },
              {
                first: 'https://mdbootstrap.com/img/Photos/Others/images/25.webp',
                second: 'https://mdbootstrap.com/img/Photos/Others/images/24.webp',
              },
              {
                first: 'https://mdbootstrap.com/img/Photos/Others/images/31.webp',
                second: 'https://mdbootstrap.com/img/Photos/Others/images/23.webp',
              },
            ]);
          
            const handleScroll = () => {
              if (imgCounter > newImages.length - 1) {
                return;
              }
          
              setImages([...images, newImages[imgCounter]]);
              setImgCounter(imgCounter + 1);
            };
            
            return (
              <main className='my-4'>
                <MDBContainer>
                  <MDBInfiniteScroll windowParent onInfiniteScroll={handleScroll} tag='section' className='text-center mb-4'>
                    {images.map((img, index) => (
                      <MDBRow key={index}>
                        <MDBCol md='6' className='mb-4'>
                          <MDBRipple
                            rippleTag='div'
                            className='bg-image hover-overlay shadow-1-strong rounded mb-4'
                            rippleColor='light'
                          >
                            <img src={img.first} className='w-100' />
                            <a href='#!'>
                              <div className='mask' style={{ backgroundColor: 'rgba(251, 251, 251, 0.2)' }}></div>
                            </a>
                          </MDBRipple>
                          <h5>This is an title of the article</h5>
          
                          <p>
                            Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus
                            laudantium cum dolorem illo. Quos architecto deserunt saepe.
                          </p>
          
                          <MDBBtn rounded color='info' href='#!'>
                            Read more
                          </MDBBtn>
                        </MDBCol>
          
                        <MDBCol md='6' className='mb-4'>
                          <MDBRipple
                            rippleTag='div'
                            className='bg-image hover-overlay shadow-1-strong rounded mb-4'
                            rippleColor='light'
                          >
                            <img src={img.second} className='w-100' />
                            <a href='#!'>
                              <div className='mask' style={{ backgroundColor: 'rgba(251, 251, 251, 0.2)' }}></div>
                            </a>
                          </MDBRipple>
                          <h5>This is an title of the article</h5>
          
                          <p>
                            Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus
                            laudantium cum dolorem illo. Quos architecto deserunt saepe.
                          </p>
          
                          <MDBBtn rounded color='info' href='#!'>
                            Read more
                          </MDBBtn>
                        </MDBCol>
                      </MDBRow>
                    ))}
          
                    <MDBRow id='spinner' style={{ display: 'none' }}>
                      <div className='col-md-12'>
                        <div className='spinner-border mx-auto'></div>
                      </div>
                    </MDBRow>
                  </MDBInfiniteScroll>
                </MDBContainer>
              </main>
            );
          }
          
        
    

Infinite scroll - API


Import

        
            
          import { MDBInfiniteScroll } from 'mdb-react-ui-kit';
        
        
    

Properties

MDBInfiniteScroll

Name Type Default Description Example
infiniteScrollRef Reference '' A reference for the MDBInfiniteScroll element <MDBInfiniteScroll infiniteScrollRef={exampleReactRef} />
infiniteDirection String 'y' Defines an example scroll direction. <MDBInfiniteScroll infiniteDirection='x' />
tag String 'div' Defines tag of the MDBInfiniteScroll element <MDBInfiniteScroll tag="section" />
windowParent Boolean 'false' Sets window as a parent of MDBInfiniteScroll <MDBInfiniteScroll windowParent />

Events

MDBInfiniteScroll

Name Type Description
onInfiniteScroll () => any This event fires immediately after scrolling to the end of the container.
onComplete () => any This event fires immediately when the scrolling is completed.