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

相关文章

前端如何通过nginx访问本地端口

《前端如何通过nginx访问本地端口》:本文主要介绍前端如何通过nginx访问本地端口的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、nginx安装1、下载(1)下载地址(2)系统选择(3)版本选择2、安装部署(1)解压(2)配置文件修改(3)启动(4)

HTML中meta标签的常见使用案例(示例详解)

《HTML中meta标签的常见使用案例(示例详解)》HTMLmeta标签用于提供文档元数据,涵盖字符编码、SEO优化、社交媒体集成、移动设备适配、浏览器控制及安全隐私设置,优化页面显示与搜索引擎索引... 目录html中meta标签的常见使用案例一、基础功能二、搜索引擎优化(seo)三、社交媒体集成四、移动

HTML input 标签示例详解

《HTMLinput标签示例详解》input标签主要用于接收用户的输入,随type属性值的不同,变换其具体功能,本文通过实例图文并茂的形式给大家介绍HTMLinput标签,感兴趣的朋友一... 目录通用属性输入框单行文本输入框 text密码输入框 password数字输入框 number电子邮件输入编程框

HTML img标签和超链接标签详细介绍

《HTMLimg标签和超链接标签详细介绍》:本文主要介绍了HTML中img标签的使用,包括src属性(指定图片路径)、相对/绝对路径区别、alt替代文本、title提示、宽高控制及边框设置等,详细内容请阅读本文,希望能对你有所帮助... 目录img 标签src 属性alt 属性title 属性width/h

CSS3打造的现代交互式登录界面详细实现过程

《CSS3打造的现代交互式登录界面详细实现过程》本文介绍CSS3和jQuery在登录界面设计中的应用,涵盖动画、选择器、自定义字体及盒模型技术,提升界面美观与交互性,同时优化性能和可访问性,感兴趣的朋... 目录1. css3用户登录界面设计概述1.1 用户界面设计的重要性1.2 CSS3的新特性与优势1.

HTML5 中的<button>标签用法和特征

《HTML5中的<button>标签用法和特征》在HTML5中,button标签用于定义一个可点击的按钮,它是创建交互式网页的重要元素之一,本文将深入解析HTML5中的button标签,详细介绍其属... 目录引言<button> 标签的基本用法<button> 标签的属性typevaluedisabled

HTML5实现的移动端购物车自动结算功能示例代码

《HTML5实现的移动端购物车自动结算功能示例代码》本文介绍HTML5实现移动端购物车自动结算,通过WebStorage、事件监听、DOM操作等技术,确保实时更新与数据同步,优化性能及无障碍性,提升用... 目录1. 移动端购物车自动结算概述2. 数据存储与状态保存机制2.1 浏览器端的数据存储方式2.1.

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

CSS place-items: center解析与用法详解

《CSSplace-items:center解析与用法详解》place-items:center;是一个强大的CSS简写属性,用于同时控制网格(Grid)和弹性盒(Flexbox)... place-items: center; 是一个强大的 css 简写属性,用于同时控制 网格(Grid) 和 弹性盒(F

CSS实现元素撑满剩余空间的五种方法

《CSS实现元素撑满剩余空间的五种方法》在日常开发中,我们经常需要让某个元素占据容器的剩余空间,本文将介绍5种不同的方法来实现这个需求,并分析各种方法的优缺点,感兴趣的朋友一起看看吧... css实现元素撑满剩余空间的5种方法 在日常开发中,我们经常需要让某个元素占据容器的剩余空间。这是一个常见的布局需求