Implementing Infinite Scroll Into a React Component

本文主要是介绍Implementing Infinite Scroll Into a React Component,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

In our face-paced modern society, who has time to click through pages and pages of content? “Not I,” said the web developer. In a world full of shortcuts, swipes and other gestures, the most efficient way to get through pages of content is the infinite scroll.

While not a new concept, the idea of infinite scroll is still somewhat controversial. Like most things, it has a time and a place in modern web design when properly implemented.

For anybody unfamiliar, infinite scroll is the concept of new content being loaded as you scroll down a page. When you get to the bottom of the content, the site automatically loads new content and appends it to the bottom.

Infinite scroll may not be ideal for all types of content, it is especially useful of feeds of data that an end-user would most probably want to page through quickly.

A perfect use case, and one you may already be familiar with is Instagram. You are presented with a feed of images and as you scroll down, more images keep showing up. Over and over and over until they run out of content to give you.

This article will teach you how to implement the infinite scroll concept into a React component and uses the Random User Generator to load a list of users from.

? Alligator.io recommends ⤵

⚛️ Fullstack Advanced React & GraphQL by Wes Bos

ⓘ About this affiliate link


Before we begin, we need to make sure we have the proper dependencies in our project. To load data from the Random User Generator we are going to use superagent.

For debouncing of the events (more on that in a bit), we’re going to use lodash:

To add superagent and lodash.debounce to your project via npm run:

$ npm install --save superagent lodash.debounce

Or via yarn:

$ yarn add superagent lodash.debounce

The crux of our infinite scroll component is going to be an onscroll event that will check to see if the user has scrolled to the bottom of the page. Upon reaching the bottom of the page, our event will attempt to load additional content.

When binding events, especially to scroll events, it’s good practice to debounce the events. Debouncing is when you only run a function once it a specified amount of time has passed since it was last called.

Debouncing improves performance for your user by limiting how often an event if fired and also helps take some strain off of any services you may be calling from the event handler.

window.onscroll = debounce(() => {if (window.innerHeight + document.documentElement.scrollTop=== document.documentElement.offsetHeight) {// Do awesome stuff like loading more content!}
}, 100);

The data that has been loaded will be appended to an array in the component’s state and will be iterated through in the component’s render method.

All good things come to an end. For demonstration purposes our component will eventually stop loading new content and display a message that it's reached the end and there is no additional content.


Now that we understand the logic flow that’s necessary to implement infinite scroll, let’s dive into our component:

import React, { Component, Fragment } from "react";
import { render } from "react-dom";
import request from "superagent";
import debounce from "lodash.debounce";class InfiniteUsers extends Component {constructor(props) {super(props);// Sets up our initial statethis.state = {error: false,hasMore: true,isLoading: false,users: [],};// Binds our scroll event handlerwindow.onscroll = debounce(() => {const {loadUsers,state: {error,isLoading,hasMore,},} = this;// Bails early if:// * there's an error// * it's already loading// * there's nothing left to loadif (error || isLoading || !hasMore) return;// Checks that the page has scrolled to the bottomif (window.innerHeight + document.documentElement.scrollTop=== document.documentElement.offsetHeight) {loadUsers();}}, 100);}componentWillMount() {// Loads some users on initial loadthis.loadUsers();}loadUsers = () => {this.setState({ isLoading: true }, () => {request.get('https://randomuser.me/api/?results=10').then((results) => {// Creates a massaged array of user dataconst nextUsers = results.body.results.map(user => ({email: user.email,name: Object.values(user.name).join(' '),photo: user.picture.medium,username: user.login.username,uuid: user.login.uuid,}));// Merges the next users into our existing usersthis.setState({// Note: Depending on the API you're using, this value may// be returned as part of the payload to indicate that there// is no additional data to be loadedhasMore: (this.state.users.length < 100),isLoading: false,users: [...this.state.users,...nextUsers,],});}).catch((err) => {this.setState({error: err.message,isLoading: false,});})});}render() {const {error,hasMore,isLoading,users,} = this.state;return (<div><h1>Infinite Users!</h1><p>Scroll down to load more!!</p>{users.map(user => (<Fragment key={user.username}><hr /><div style={{ display: 'flex' }}><imgalt={user.username}src={user.photo}style={{borderRadius: '50%',height: 72,marginRight: 20,width: 72,}}/><div><h2 style={{ marginTop: 0 }}>@{user.username}</h2><p>Name: {user.name}</p><p>Email: {user.email}</p></div></div></Fragment>))}<hr />{error &&<div style={{ color: '#900' }}>{error}</div>}{isLoading &&<div>Loading...</div>}{!hasMore &&<div>You did it! You reached the end!</div>}</div>);}
}const container = document.createElement("div");
document.body.appendChild(container);
render(<InfiniteUsers />, container);

There’s really not much to it!

The component manages a few status flags and list of data in it’s state, the onscroll event does most of the heavy lifting and the render method brings it to life on your screen!

We’re also making use of setState with a callback function passed-in as the second argument. The initial call to setState in our loadUsers method sets the value of loading to true and then in the callback function we load some users and call setState again to append our new users to the users already in the state.


I hope you’ve found this article on implementing infinite scroll in React informative.

If interested, you can find a working demo of this component over on CodeSandbox.

这篇关于Implementing Infinite Scroll Into a React Component的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/980746

相关文章

HTML5中的Microdata与历史记录管理详解

《HTML5中的Microdata与历史记录管理详解》Microdata作为HTML5新增的一个特性,它允许开发者在HTML文档中添加更多的语义信息,以便于搜索引擎和浏览器更好地理解页面内容,本文将探... 目录html5中的Mijscrodata与历史记录管理背景简介html5中的Microdata使用M

html5的响应式布局的方法示例详解

《html5的响应式布局的方法示例详解》:本文主要介绍了HTML5中使用媒体查询和Flexbox进行响应式布局的方法,简要介绍了CSSGrid布局的基础知识和如何实现自动换行的网格布局,详细内容请阅读本文,希望能对你有所帮助... 一 使用媒体查询响应式布局        使用的参数@media这是常用的

HTML5表格语法格式详解

《HTML5表格语法格式详解》在HTML语法中,表格主要通过table、tr和td3个标签构成,本文通过实例代码讲解HTML5表格语法格式,感兴趣的朋友一起看看吧... 目录一、表格1.表格语法格式2.表格属性 3.例子二、不规则表格1.跨行2.跨列3.例子一、表格在html语法中,表格主要通过< tab

Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

前端CSS Grid 布局示例详解

《前端CSSGrid布局示例详解》CSSGrid是一种二维布局系统,可以同时控制行和列,相比Flex(一维布局),更适合用在整体页面布局或复杂模块结构中,:本文主要介绍前端CSSGri... 目录css Grid 布局详解(通俗易懂版)一、概述二、基础概念三、创建 Grid 容器四、定义网格行和列五、设置行

前端下载文件时如何后端返回的文件流一些常见方法

《前端下载文件时如何后端返回的文件流一些常见方法》:本文主要介绍前端下载文件时如何后端返回的文件流一些常见方法,包括使用Blob和URL.createObjectURL创建下载链接,以及处理带有C... 目录1. 使用 Blob 和 URL.createObjectURL 创建下载链接例子:使用 Blob

Vuex Actions多参数传递的解决方案

《VuexActions多参数传递的解决方案》在Vuex中,actions的设计默认只支持单个参数传递,这有时会限制我们的使用场景,下面我将详细介绍几种处理多参数传递的解决方案,从基础到高级,... 目录一、对象封装法(推荐)二、参数解构法三、柯里化函数法四、Payload 工厂函数五、TypeScript

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo

CSS Padding 和 Margin 区别全解析

《CSSPadding和Margin区别全解析》CSS中的padding和margin是两个非常基础且重要的属性,它们用于控制元素周围的空白区域,本文将详细介绍padding和... 目录css Padding 和 Margin 全解析1. Padding: 内边距2. Margin: 外边距3. Padd