React Bootstrap Scrollspy MDB Pro component

React Scrollspy - Bootstrap 4 & Material Design

Note: This documentation is for an older version of Bootstrap (v.4). A newer version is available for Bootstrap 5. We recommend migrating to the latest version of our product - Material Design for Bootstrap 5.
Go to docs v.5

React Bootstrap scrollspy autmatically updates tabs, navigation or list group components based on scroll position to indicate which link is currently active in the viewport.



Example with list group

Scrollspy also works with ListGroup. Scroll the area next to the list group and watch the active class change.

section1

Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle rights whatever. Anim keffiyeh carles cardigan. Velit seitan mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean shorts, williamsburg hoodie minim qui you probably haven't heard of them et cardigan trust fund culpa biodiesel wes anderson aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh artisan ullamco consequat.

Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle rights whatever. Anim keffiyeh carles cardigan. Velit seitan mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean shorts, williamsburg hoodie minim qui you probably haven't heard of them et cardigan trust fund culpa biodiesel wes anderson aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh artisan ullamco consequat.

section2

Veniam marfa mustache skateboard, adipisicing fugiat velit pitchfork beard. Freegan beard aliqua cupidatat mcsweeney's vero. Cupidatat four loko nisi, ea helvetica nulla carles. Tattooed cosby sweater food truck, mcsweeney's quis non freegan vinyl. Lo-fi wes anderson +1 sartorial. Carles non aesthetic exercitation quis gentrify. Brooklyn adipisicing craft beer vice keytar deserunt.

Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle rights whatever. Anim keffiyeh carles cardigan. Velit seitan mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean shorts, williamsburg hoodie minim qui you probably haven't heard of them et cardigan trust fund culpa biodiesel wes anderson aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh artisan ullamco consequat.

section3

Occaecat commodo aliqua delectus. Fap craft beer deserunt skateboard ea. Lomo bicycle rights adipisicing banh mi, velit ea sunt next level locavore single-origin coffee in magna veniam. High life id vinyl, echo park consequat quis aliquip banh mi pitchfork. Vero VHS est adipisicing. Consectetur nisi DIY minim messenger bag. Cred ex in, sustainable delectus consectetur fanny pack iphone.

Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle rights whatever. Anim keffiyeh carles cardigan. Velit seitan mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean shorts, williamsburg hoodie minim qui you probably haven't heard of them et cardigan trust fund culpa biodiesel wes anderson aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh artisan ullamco consequat.

section4

Veniam marfa mustache skateboard, adipisicing fugiat velit pitchfork beard. Freegan beard aliqua cupidatat mcsweeney's vero. Cupidatat four loko nisi, ea helvetica nulla carles. Tattooed cosby sweater food truck, mcsweeney's quis non freegan vinyl. Lo-fi wes anderson +1 sartorial. Carles non aesthetic exercitation quis gentrify. Brooklyn adipisicing craft beer vice keytar deserunt.

Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle rights whatever. Anim keffiyeh carles cardigan. Velit seitan mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean shorts, williamsburg hoodie minim qui you probably haven't heard of them et cardigan trust fund culpa biodiesel wes anderson aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh artisan ullamco consequat.


        import React from "react";
        import { MDBScrollspyBox, MDBScrollspyText, MDBListGroup, MDBListGroupItem, MDBRow, MDBCol } from "mdbreact";

        class ScrollSpyPage extends React.Component {
        constructor(props) {
        super(props);
        this.state = {
        active: 0,
        sections: []
        };

        this.scrollSpyText = React.createRef();
        }

        componentDidMount() {
        let sections = this.scrollSpyText.current.getElementsByTagName("h4");
        this.setState({ sections });
        }

        handleScroll = (e) => {
        const scrollTop = e.target.scrollTop;
        const sections = this.state.sections;
        const lastIndex = sections.length - 1;

        for (let i = 0; i < lastIndex; i++) { if ((scrollTop> sections[i].offsetTop - 20) && (scrollTop < sections[i +
            1].offsetTop - 20)) { this.setState({ active: i }); } }; if (scrollTop> sections[lastIndex].offsetTop - 20)
            this.setState({ active: lastIndex });
            }

        render() {
          return (
            <MDBScrollspyBox>
              <MDBRow>
                <MDBCol md="3">
                  <MDBListGroup>
                    <MDBListGroupItem href="#section1" active={this.state.active===0}>section1</MDBListGroupItem>
                    <MDBListGroupItem href="#section2" active={this.state.active===1}>section2</MDBListGroupItem>
                    <MDBListGroupItem href="#section3" active={this.state.active===2}>section3</MDBListGroupItem>
                    <MDBListGroupItem href="#section4" active={this.state.active===3}>section4</MDBListGroupItem>
                  </MDBListGroup>
                </MDBCol>
                <MDBCol>
                  <MDBScrollspyText onScroll={this.handleScroll} scrollSpyRef={this.scrollSpyText}>
                    <h4 id="section1">section1</h4>
                    <p>
                      Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr
                      enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle
                      rights whatever. Anim keffiyeh carles cardigan. Velit seitan
                      mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean
                      shorts, williamsburg hoodie minim qui you probably haven't heard
                      of them et cardigan trust fund culpa biodiesel wes anderson
                      aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh
                      artisan ullamco consequat.
                    </p>
                    <p>
                      Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr
                      enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle
                      rights whatever. Anim keffiyeh carles cardigan. Velit seitan
                      mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean
                      shorts, williamsburg hoodie minim qui you probably haven't heard
                      of them et cardigan trust fund culpa biodiesel wes anderson
                      aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh
                      artisan ullamco consequat.
                    </p>
                    <h4 id="section2">section2</h4>
                    <p>
                      Veniam marfa mustache skateboard, adipisicing fugiat velit
                      pitchfork beard. Freegan beard aliqua cupidatat mcsweeney's vero.
                      Cupidatat four loko nisi, ea helvetica nulla carles. Tattooed
                      cosby sweater food truck, mcsweeney's quis non freegan vinyl.
                      Lo-fi wes anderson +1 sartorial. Carles non aesthetic exercitation
                      quis gentrify. Brooklyn adipisicing craft beer vice keytar
                      deserunt.
                    </p>
                    <p>
                      Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr
                      enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle
                      rights whatever. Anim keffiyeh carles cardigan. Velit seitan
                      mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean
                      shorts, williamsburg hoodie minim qui you probably haven't heard
                      of them et cardigan trust fund culpa biodiesel wes anderson
                      aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh
                      artisan ullamco consequat.
                    </p>
                    <h4 id="section3">section3</h4>
                    <p>
                      Occaecat commodo aliqua delectus. Fap craft beer deserunt
                      skateboard ea. Lomo bicycle rights adipisicing banh mi, velit ea
                      sunt next level locavore single-origin coffee in magna veniam.
                      High life id vinyl, echo park consequat quis aliquip banh mi
                      pitchfork. Vero VHS est adipisicing. Consectetur nisi DIY minim
                      messenger bag. Cred ex in, sustainable delectus consectetur fanny
                      pack iphone.
                    </p>
                    <p>
                      Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr
                      enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle
                      rights whatever. Anim keffiyeh carles cardigan. Velit seitan
                      mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean
                      shorts, williamsburg hoodie minim qui you probably haven't heard
                      of them et cardigan trust fund culpa biodiesel wes anderson
                      aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh
                      artisan ullamco consequat.
                    </p>
                    <h4 id="section4">section4</h4>
                    <p>
                      Veniam marfa mustache skateboard, adipisicing fugiat velit
                      pitchfork beard. Freegan beard aliqua cupidatat mcsweeney's vero.
                      Cupidatat four loko nisi, ea helvetica nulla carles. Tattooed
                      cosby sweater food truck, mcsweeney's quis non freegan vinyl.
                      Lo-fi wes anderson +1 sartorial. Carles non aesthetic exercitation
                      quis gentrify. Brooklyn adipisicing craft beer vice keytar
                      deserunt.
                    </p>
                    <p>
                      Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr
                      enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle
                      rights whatever. Anim keffiyeh carles cardigan. Velit seitan
                      mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean
                      shorts, williamsburg hoodie minim qui you probably haven't heard
                      of them et cardigan trust fund culpa biodiesel wes anderson
                      aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh
                      artisan ullamco consequat.
                    </p>
                  </MDBScrollspyText>
                </MDBCol>
              </MDBRow>
            </MDBScrollspyBox>
            );
          }
        }

        export default ScrollSpyPage;
      

React Scrollspy - API

In this section you will find advanced information about the Scrollspy component. You will learn which modules are required in this component, what are the possibilities of configuring the component, and what events and methods you can use in working with it.


Import statement

React scrollspy can use other components, like ListGropu or Navbar in addition to present current scroll location, so rememeber about proper imports.

Main Scrollspy components:


        import { MDBScrollspyBox, MDBScrollspyList, MDBScrollspyListItem, MDBScrollspyText  } from "mdbreact";
      

Import statement

In order to use Scrollspay you have to define scrollable container, and sections inside of it and determine which section is visible.

Our suggestion is to use React ref to watch it's offsetTop property. Then we compare it with offsetTop of nested sections to determine which is active.

Also rememeber that Scrollspy elements (sections and navigation) have to be wrapped inside MDBScrollspyBox and sections have to be inside MDBScrollspyTex.

Sample code looks like this:


          import React from "react";
          import ReactDOM from 'react-dom';
          import {
          MDBScrollspyBox,
          MDBScrollspyList,
          MDBScrollspyListItem,
          MDBScrollspyText
          } from "mdbreact";
          import DocsLink from "../DocsLink";

          class ScrollSpyPage extends React.Component {
          constructor(props) {
            super(props);
            this.state = {
              active: 0,
              sections: []
            };

            this.scrollSpyText = React.createRef();
          }

          componentDidMount() {
            let sections = this.scrollSpyText.current.getElementsByTagName("h4");
            this.setState({ sections });
          }

          handleScroll = (e) => {
            const scrollTop = e.target.scrollTop;
            const sections = this.state.sections;
            const lastIndex = sections.length - 1;

            for (let i = 0; i < lastIndex; i++) { if ((scrollTop> sections[i].offsetTop - 20) && (scrollTop < sections[i +
              1].offsetTop - 20)) { this.setState({ active: i }); } }; if (scrollTop> sections[lastIndex].offsetTop - 20)
              this.setState({ active: lastIndex });
          }

          render() {
            return (
              <MDBScrollspyBox>
                <MDBScrollspyList>
                  <MDBScrollspyListItem href="#section1" active={this.state.active===0}>
                    section1
                  </MDBScrollspyListItem>
                  <MDBScrollspyListItem href="#section2" active={this.state.active===1}>
                    section2
                  </MDBScrollspyListItem>
                  <MDBScrollspyListItem href="#section3" active={this.state.active===2}>
                    section3
                  </MDBScrollspyListItem>
                </MDBScrollspyList>
                <MDBScrollspyText onScroll={this.handleScroll} scrollSpyRef={this.scrollSpyText}>
                  <div id="section1">section1</div>
                  <div id="section2">section2</div>
                  <div id="section3">section3</div>
                </MDBScrollspyText>
              </MDBScrollspyBox>
            );
          }
        }

        export default ScrollSpyPage;

      

API Reference: ScrollspyBox Properties

The table below shows the configuration options of the MDBScrollspyBox component.

Name Type Default Description Example
className String Adds custom class to the Stepper component <MDBScrollspyBox className="myClass" />

API Reference: ScrollspyText Properties

The table below shows the configuration options of the MDBScrollspyText component.

Name Type Default Description Example
className String Adds custom class to the Stepper component <MDBScrollspyText className="myClass" />
scrollSpyRef oneOfType[function, object] The React Ref which points on to the div wrapping all the scrollspy content <MDBScrollspyText scrollSpyRef={this.scrollspyRef} />

API Reference: ScrollspyList Properties

The table below shows the configuration options of the MDBScrollspyList component.

Name Type Default Description Example
className String Adds custom class to the Stepper component <MDBScrollspyList className="myClass" />
color String default Changes the background color of the tab scrollspy panel <MDBScrollspyList color="indigo" />

API Reference: ScrollspyListItem Properties

The table below shows the configuration options of the MDBScrollspyListItem component.

Name Type Default Description Example
active Boolean false Sets active state of the list item <MDBScrollspyListItem active={true} />
className String Adds custom class to the Stepper component <MDBScrollspyListItem className="myClass" />