Infinite Scroll In React JS

Infinite Scroll In React Js
Project: Infinite Scroll in React - BabyNames
Author: CodeMeNow
Edit Online: View on CodePen
License: MIT

This React JS component helps you to create an infinite scroll by adding lazy load functionality on the webpage. It gets the data from an array and loads a few items on the page load. When the user scrolls down the page, it requests the next data, and so on. You can set the initial offset of the data and the number of items per request.

Basically, this component demonstrates the list of the baby’s names in the array, but you can define your own array of data that you want to load with an infinite scroll. Thus, it will avoid loading unnecessary data and improve performance and user experience.

How to Create Infinite Scroll In React JS

Create the HTML structure as follows:

<div id="app-wrapper">
  <div id="app"></div>
</div>

Add the following CSS styles for the basic UI of the infinite scroll page. These CSS rules are optional, you can style the page accordion to your needs.

html,
body {
  margin: 0;
  padding: 0;
  background-color: #a5da7e;
}
#app-wrapper {
  margin: 16px 128px 128px 128px;
  text-align: center;
background: #1f4037;  /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #99f2c8, #1f4037);  /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #99f2c8, #1f4037); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */

padding: 90px;
border-radius: 20px;
}
h2 {
  font-size: 64px;
  font-family: cursive;
  color: indigo;
  margin: 0;
}
li.baby-name-row {
  padding: 4px 0 4px 0;
  font-size: 32px;
  font-weight: 500;
  font-family: cursive;
  color: #fff;
}

li.baby-name-row.loading::after {
  content: "\A . . . Loading More Names . . .";
  white-space: pre;
  margin: 12px;
  background-color: orange;
}

Load the React library by adding the following CDN links before closing the body tag:

<script src='https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js'></script>

Finally, add the following JavaScript function to your project and update the array of grilNames with your data.

const girlNames = [
"Aaliyah",
"Abby",
"Abigail",
"Ada",
"Adalee",
"Adaline",
"Adalyn",
"Adalynn",
"Addilyn",
"Addilynn",
"Addison",
"Addisyn",
"Addyson",
"Adelaide",
"Adele",
"Adelina",
"Adeline",
"Adelyn",
"Adelynn",
"Adley",
"Adriana",
"Adrianna",
"Adrienne",
"Ailani",
"Aileen*",
"Ainsley",
"Aisha",
"Aislinn",
"Aitana",
"Aiyana",
"Alaia",
"Alaina",
"Alana",
"Alani",
"Alanna",
"Alannah",
"Alaya",
"Alayah",
"Alayna",
"Aleah",
"Aleena",
"Alejandra",
"Alena",
"Alessandra",
"Alessia",
"Alexa",
"Alexandra",
"Alexandria",
"Alexia",
"Alexis",
"Alia",
"Aliana",
"Alianna",
"Alice",
"Alicia",
"Alina",
"Alisha",
"Alison",
"Alisson",
"Alivia",
"Aliya",
"Aliyah",
"Aliza",
"Allie",
"Allison",
"Allyson",
"Alma",
"Alondra",
"Alora",
"Alyson",
"Alyssa",
"Amaia",
"Amalia",
"Amanda",
"Amani",
"Amara",
"Amari",
"Amaris",
"Amaya",
"Amayah",
"Amber",
"Amelia",
"Amelie",
"Amia",
"Amina",
"Amira",
"Amirah",
"Amiya",
"Amiyah",
"Amora",
"Amy",
"Ana",
"Anahi",
"Anais",
"Analia",
"Anastasia",
"Anaya",
"Andi",
"Andrea",
"Angel",
"Angela",
"Angelica",
"Angelina",
"Angie",
"Anika",
"Aniya",
"Aniyah",
"Ann",
"Anna",
"Annabel",
"Annabella",
"Annabelle",
"Annalee",
"Annalise",
"Anne",
"Annie",
"Annika",
"Ansley",
"Antonella",
"Anya",
"April",
"Arabella",
"Arden",
"Arely",
"Ari",
"Aria",
"Ariadne",
"Ariah",
"Ariana",
"Arianna",
"Ariel",
"Ariella",
"Arielle",
"Ariya",
"Ariyah",
"Arlette",
"Armani",
"Arya",
"Ashley",
"Ashlyn",
"Ashlynn",
"Aspen",
"Astrid",
"Athena",
"Aubree",
"Aubrey",
"Aubrie",
"Aubriella",
"Aubrielle",
"Audrey",
"August",
"Aurelia",
"Aurora",
"Austyn",
"Autumn",
"Ava",
"Avah",
"Avalyn",
"Avalynn",
"Averi",
"Averie",
"Avery",
"Aviana",
"Avianna",
"Aya",
"Ayla",
"Ayleen",
"Aylin",
"Azalea",
"Azaria",
"Azariah",
"Bailee",
"Bailey",
"Barbara",
"Baylee",
"Beatrice",
"Belen",
"Bella",
"Bellamy",
"Belle",
"Berkley",
"Bethany",
"Bexley",
"Bianca",
"Blair",
"Blaire",
"Blake",
"Blakely",
"Bonnie",
"Braelyn",
"Braelynn",
"Braylee",
"Bria",
"Briana",
"Brianna",
"Briar",
"Bridget",
"Briella",
"Brielle",
"Brinley",
"Bristol",
"Brittany",
"Brooke",
"Brooklyn",
"Brooklynn",
"Brylee",
"Brynlee",
"Brynleigh",
"Brynn",
"Cadence",
"Cali",
"Callie",
"Calliope",
"Cameron",
"Camila",
"Camilla",
"Camille",
"Camryn",
"Cara",
"Carly",
"Carmen",
"Carolina",
"Caroline",
"Carolyn",
"Carter",
"Casey",
"Cassandra",
"Cassidy",
"Cataleya",
"Catalina",
"Catherine",
"Cecelia",
"Cecilia",
"Celeste",
"Celia",
"Celine",
"Chana",
"Chanel",
"Charlee",
"Charleigh",
"Charley",
"Charli",
"Charlie",
"Charlotte",
"Chaya",
"Chelsea",
"Cheyenne",
"Chloe",
"Christina",
"Christine",
"Claire",
"Clara",
"Clare",
"Clarissa",
"Claudia",
"Clementine",
"Colette",
"Collins",
"Cora",
"Coraline",
"Corinne",
"Crystal",
"Cynthia",
"Dahlia",
"Daisy*",
"Dakota",
"Dalary",
"Daleyza",
"Dallas",
"Dana",
"Dani",
"Daniela",
"Daniella",
"Danielle",
"Danna",
"Daphne",
"Davina",
"Dayana",
"Deborah",
"Delaney",
"Delilah",
"Della",
"Demi",
"Destiny",
"Diana",
"Dior",
"Dorothy",
"Dream",
"Dulce",
"Dylan",
"Eden",
"Edith",
"Egypt",
"Eileen",
"Elaina",
"Elaine",
"Eleanor",
"Elena",
"Eliana",
"Elianna",
"Elina",
"Elisa",
"Elisabeth",
"Elise",
"Eliza",
"Elizabeth",
"Ella",
"Elle",
"Ellen",
"Elliana",
"Ellianna",
"Ellie",
"Elliot",
"Elliott",
"Ellis",
"Ellison",
"Eloise",
"Elora",
"Elsa",
"Elsie",
"Elyse",
"Ember",
"Emberly",
"Emelia",
"Emely",
"Emerie",
"Emerson",
"Emersyn",
"Emery",
"Emilee",
"Emilia",
"Emily",
"Emma",
"Emmaline",
"Emmalyn",
"Emmalynn",
"Emmarie",
"Emmeline",
"Emmie",
"Emmy",
"Emory",
"Ensley",
"Erica",
"Erika",
"Erin",
"Esme",
"Esmeralda",
"Esperanza",
"Estella",
"Estelle",
"Esther",
"Estrella",
"Etta",
"Eva",
"Evangeline",
"Eve",
"Evelyn",
"Evelynn",
"Everlee",
"Everleigh",
"Everly",
"Evie",
"Ezra",
"Faith",
"Fatima",
"Faye",
"Felicity",
"Fernanda",
"Finley",
"Fiona",
"Florence",
"Frances",
"Francesca",
"Frankie",
"Freya",
"Frida",
"Gabriela",
"Gabriella",
"Gabrielle",
"Galilea",
"Gemma",
"Genesis",
"Genevieve",
"Georgia",
"Gia",
"Giana",
"Gianna",
"Giavanna",
"Giovanna",
"Giselle",
"Giuliana",
"Gloria",
"Grace",
"Gracelyn",
"Gracelynn",
"Gracie",
"Greta",
"Guadalupe",
"Gwen",
"Gwendolyn",
"Hadassah",
"Hadlee",
"Hadleigh",
"Hadley",
"Hailee",
"Hailey",
"Haisley",
"Haley",
"Halle",
"Hallie",
"Hana",
"Hanna",
"Hannah",
"Harlee",
"Harleigh",
"Harley",
"Harlow",
"Harmoni",
"Harmony",
"Harper",
"Hattie",
"Haven",
"Hayden",
"Haylee",
"Hayley",
"Hazel",
"Heaven",
"Heavenly",
"Heidi",
"Helen",
"Helena",
"Henley",
"Holland*",
"Holly",
"Hope",
"Hunter",
"Iliana",
"Imani",
"India",
"Ingrid",
"Irene",
"Iris",
"Isabel",
"Isabela",
"Isabella",
"Isabelle",
"Isla",
"Itzayana",
"Itzel",
"Ivanna",
"Ivory",
"Ivy",
"Izabella",
"Jacqueline",
"Jada",
"Jade",
"Jaelyn",
"Jaelynn",
"Jaliyah",
"Jamie",
"Jana",
"Jane",
"Janelle",
"Janessa",
"Janiyah",
"Jasmine",
"Jaycee",
"Jayda",
"Jayde",
"Jayden",
"Jayla",
"Jaylah",
"Jaylee",
"Jayleen",
"Jaylene",
"Jazlyn",
"Jazlynn",
"Jazmin",
"Jazmine",
"Jemma",
"Jenesis",
"Jenna",
"Jennifer",
"Jessica",
"Jessie",
"Jewel",
"Jillian",
"Jimena",
"Joanna",
"Jocelyn",
"Joelle",
"Johanna",
"Jolene",
"Jolie",
"Jordan",
"Jordyn",
"Joselyn",
"Josephine",
"Josie",
"Journee",
"Journey",
"Journi",
"Joy",
"Joyce",
"Judith",
"Julia",
"Juliana",
"Julianna",
"Julie",
"Juliet",
"Julieta",
"Juliette",
"Julissa",
"June",
"Juniper",
"Jurnee",
"Justice",
"Kadence",
"Kaelyn",
"Kai",
"Kaia",
"Kailani",
"Kailey",
"Kailyn",
"Kairi",
"Kaitlyn",
"Kaiya",
"Kalani",
"Kali",
"Kaliyah",
"Kallie",
"Kamila",
"Kamilah",
"Kamiyah",
"Kamryn",
"Kara",
"Karen",
"Karina",
"Karla",
"Karlee",
"Karsyn",
"Karter",
"Kassidy",
"Kataleya",
"Katalina",
"Kate",
"Katelyn",
"Katherine",
"Kathleen",
"Kathryn",
"Katie",
"Kaydence",
"Kayla",
"Kaylani",
"Kaylee",
"Kayleigh",
"Kaylie",
"Kaylin",
"Kehlani",
"Keilani",
"Keily",
"Keira",
"Kelly",
"Kelsey",
"Kendall",
"Kendra",
"Kenia",
"Kenley",
"Kenna",
"Kennedi",
"Kennedy",
"Kensley",
"Kenzie",
"Keyla",
"Khaleesi",
"Khloe",
"Kiana",
"Kiara*",
"Kiera",
"Kimber",
"Kimberly",
"Kimora",
"Kinley",
"Kinslee",
"Kinsley",
"Kira",
"Kora",
"Kori",
"Kyla",
"Kylee",
"Kyleigh",
"Kylie",
"Kynlee",
"Kyra",
"Lacey",
"Laila",
"Lailah",
"Lainey",
"Lana",
"Landry",
"Laney",
"Lara",
"Laura",
"Laurel",
"Lauren",
"Lauryn",
"Layla",
"Laylah",
"Lea",
"Leah",
"Leanna",
"Legacy",
"Leia",
"Leighton",
"Leila",
"Leilani",
"Lena",
"Lennon",
"Lennox",
"Leona",
"Leslie",
"Lexi",
"Lexie",
"Leyla",
"Lia",
"Liana",
"Liberty",
"Lila",
"Lilah",
"Lilian",
"Liliana",
"Lilianna",
"Lilith",
"Lillian",
"Lilliana",
"Lillianna",
"Lillie",
"Lilly",
"Lily",
"Lilyana",
"Lina",
"Linda",
"Lindsey",
"Lisa",
"Liv",
"Livia",
"Logan",
"Lola",
"London",
"Londyn",
"Lorelai",
"Lorelei",
"Louisa",
"Louise",
"Lucia",
"Luciana",
"Lucille",
"Lucy",
"Luella",
"Luna",
"Lyanna",
"Lydia",
"Lyla",
"Lylah",
"Lyra",
"Lyric",
"Mabel",
"Maci",
"Macie",
"Mackenzie",
"Macy",
"Madalyn",
"Madalynn",
"Maddison",
"Madeleine",
"Madeline",
"Madelyn",
"Madelynn",
"Madilyn",
"Madilynn",
"Madison",
"Madisyn",
"Mae",
"Maeve",
"Maggie",
"Magnolia",
"Maia",
"Maisie",
"Makayla",
"Makenna",
"Makenzie",
"Malani",
"Malaya",
"Malaysia*",
"Maleah",
"Malia",
"Maliah",
"Maliyah",
"Mallory",
"Mara",
"Maren",
"Margaret",
"Margo",
"Margot",
"Maria",
"Mariah",
"Mariam",
"Mariana",
"Marianna",
"Marie",
"Marilyn",
"Marina",
"Marisol",
"Marissa",
"Marlee",
"Marleigh",
"Marley",
"Martha",
"Mary",
"Maryam",
"Matilda",
"Mavis",
"Maxine",
"Maya",
"Mckenna",
"Mckenzie",
"Mckinley",
"Meadow",
"Megan",
"Meghan",
"Meilani",
"Melanie",
"Melany",
"Melina",
"Melissa",
"Melody",
"Mercy",
"Meredith",
"Mia",
"Miah",
"Micah",
"Michaela",
"Michelle",
"Mikaela",
"Mikayla",
"Mila",
"Milan",
"Milana",
"Milani",
"Milena",
"Miley",
"Millie",
"Mina",
"Mira",
"Miracle",
"Miranda",
"Miriam",
"Molly",
"Monica",
"Monroe",
"Morgan",
"Mya",
"Myah",
"Myla",
"Mylah",
"Myra",
"Nadia",
"Nala",
"Nalani",
"Nancy",
"Naomi",
"Natalia",
"Natalie",
"Nataly",
"Natasha",
"Nathalie",
"Naya",
"Nayeli",
"Nevaeh",
"Nia",
"Nicole",
"Nina",
"Noa",
"Noelle",
"Noemi",
"Nola",
"Noor",
"Nora",
"Norah",
"Nova",
"Novah",
"Novalee",
"Nyla",
"Nylah",
"Oaklee",
"Oakley",
"Oaklyn",
"Oaklynn",
"Octavia",
"Olive",
"Olivia",
"Opal",
"Ophelia",
"Paige",
"Paislee",
"Paisleigh",
"Paisley",
"Palmer",
"Paloma",
"Paola",
"Paris",
"Parker",
"Patricia",
"Paula",
"Paulina",
"Payton",
"Pearl",
"Penelope",
"Penny",
"Perla",
"Peyton",
"Phoebe",
"Phoenix",
"Piper",
"Poppy",
"Presley",
"Princess",
"Priscilla",
"Promise",
"Queen",
"Quinn",
"Rachel",
"Raegan",
"Raelyn",
"Raelynn",
"Raina",
"Ramona",
"Raquel",
"Raven",
"Rayna",
"Rayne",
"Reagan",
"Rebecca",
"Rebekah",
"Reese",
"Regina",
"Reign",
"Reina",
"Remi",
"Remington",
"Remy",
"Renata",
"Reyna",
"Rhea",
"Riley",
"River",
"Rivka",
"Robin",
"Romina",
"Rory",
"Rosa",
"Rosalee",
"Rosalie",
"Rosalyn",
"Rose",
"Roselyn",
"Rosemary",
"Rosie",
"Rowan",
"Royal",
"Royalty",
"Ruby",
"Ruth",
"Ryan",
"Ryann",
"Rylan",
"Rylee",
"Ryleigh",
"Rylie",
"Sabrina",
"Sadie",
"Sage",
"Saige",
"Salma",
"Samantha",
"Samara",
"Samira",
"Sandra",
"Saniyah",
"Saoirse",
"Sara",
"Sarah",
"Sarai",
"Sariah",
"Sariyah",
"Sasha",
"Savanna",
"Savannah",
"Sawyer",
"Saylor",
"Scarlet",
"Scarlett",
"Scarlette",
"Scout",
"Selah",
"Selena",
"Selene",
"Serena",
"Serenity",
"Shelby",
"Shiloh",
"Siena",
"Sienna",
"Sierra",
"Simone",
"Sky",
"Skye",
"Skyla",
"Skylar",
"Skyler",
"Sloan",
"Sloane",
"Sofia",
"Sophia",
"Sophie",
"Stella",
"Stephanie",
"Stevie",
"Summer",
"Sunny",
"Sutton",
"Sydney",
"Sylvia",
"Sylvie",
"Talia",
"Taliyah",
"Tatiana",
"Tatum",
"Taylor",
"Teagan",
"Tenley",
"Teresa",
"Tessa",
"Thalia",
"Thea",
"Tiana",
"Tiffany",
"Tinley",
"Tinsley",
"Tori",
"Treasure",
"Trinity",
"Vada",
"Valentina",
"Valeria",
"Valerie",
"Valery",
"Vanessa",
"Veda",
"Vera",
"Veronica",
"Victoria",
"Vienna",
"Violet",
"Violeta",
"Virginia",
"Vivian",
"Viviana",
"Vivienne",
"Waverly",
"Wendy",
"Whitley",
"Whitney",
"Willa",
"Willow",
"Winter",
"Wren",
"Wynter",
"Ximena",
"Xiomara",
"Yamileth",
"Yara",
"Yareli",
"Yaretzi",
"Zahra",
"Zainab",
"Zaniyah",
"Zara",
"Zaria",
"Zariah",
"Zariyah",
"Zaylee",
"Zelda",
"Zhavia",
"Zoe",
"Zoey",
"Zoie",
"Zola",
"Zora",
"Zuri"];

const INITIAL_OFFSET = 0;
const LIMIT = 50;
class TodoApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      offset: INITIAL_OFFSET,
      items: girlNames.slice(INITIAL_OFFSET, LIMIT) };

    this.getNextPage = this.getNextPage.bind(this);
    this.scrollHandler = this.scrollHandler.bind(this);
    this.throttledScrollHandler = _.throttle(this.scrollHandler, 250).bind(
    this);

  }

  componentDidMount() {
    console.log(document.getElementById("app-wrapper"));
    window.addEventListener("scroll", this.throttledScrollHandler);
  }
  // some notes on how we calculate the scroll based loading
  /*
    The total height of the document is the sum of the the following
    -------------------------------------------------------------------
     window.pageYOffset: number of pixels the document is currently scrolled along the vertical axis
     window.innerHeight: number of pixels of the interior height of the window in pixels
     
     The location where we want our lazy load to trigger is the sum of the following.
     note: element is the target DOM node which is our last element in the list.
    -------------------------------------------------------------------
     element.offsetTop: distance of the current element relative to the top of the offsetParent node
     element.clientHeight:  inner height of an element in pixels
  */
  scrollHandler() {
    const allBabyNameRows = document.querySelectorAll(".baby-name-row");
    const lastBabyNameRow = allBabyNameRows.length ?
    allBabyNameRows[allBabyNameRows.length - 1] :
    null;
    const moreNamesAvailable = this.state.items.length !== girlNames.length;
    if (lastBabyNameRow) {
      const lastBabyNameRowOffset =
      lastBabyNameRow.offsetTop + lastBabyNameRow.clientHeight;
      const pageOffset = window.pageYOffset + window.innerHeight;
      if (pageOffset > lastBabyNameRowOffset && moreNamesAvailable) {
        console.log("request next page");
        console.log("pageOffset", pageOffset);
        console.log("lastBabyNameRowOffset", lastBabyNameRowOffset);
        lastBabyNameRow.classList.add("loading");
        this.getNextPage().then(() => {
          lastBabyNameRow.classList.remove("loading");
        });
      }
    }
  }

  getNextPage() {
    const that = this;
    return new Promise((resolve, reject) => {
      setTimeout(function () {
        that.setState(state => {
          const nextStartingPoint = (state.offset + 1) * LIMIT;
          const nextNames = girlNames.slice(
          nextStartingPoint,
          nextStartingPoint + LIMIT);

          state.items.push(...nextNames);
          return {
            offset: state.offset + 1,
            items: state.items };

        });
        resolve();
      }, 800);
    });
  }

  render() {
    return /*#__PURE__*/(
      React.createElement("div", null, /*#__PURE__*/
      React.createElement("h2", null, "1000 Baby girl Names"), /*#__PURE__*/
      React.createElement("ol", null,
      this.state.items.map((item, index) => /*#__PURE__*/
      React.createElement("li", { key: index, className: "baby-name-row" },
      item)))));


  }}


ReactDOM.render( /*#__PURE__*/React.createElement(TodoApp, null), document.querySelector("#app"));

That’s all! hopefully, you have successfully integrated this infinite scroll component into your web/app project. If you have any questions or suggestions, feel free to comment below.

Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply