未加星标

Infinite Scrolling in React using JavaScript Generator

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二05 | 时间 2018 | 作者 红领巾 ] 0人收藏点击收藏

While reading A Quick, Practical Use Case for ES6 Generators: Building an Infinitely Repeating Array , I happened to be checking out Reddit API .

javascript Generator is a great way to infinitely return data and thought I could use it for infinite scrolling.

Let’s see how to implement infinite scrolling in React with JavaScript Generator.

:rocket: JavaScript Generator?

A generator is an easy way to implement both Iterator and Iterable protocols.

As usual, I will be lazy and refer you to these articles.

How I learned to Stop Looping and Love the Iterator Generator JavaScript MDN Documentation

In a gist, think of it as an object that returns a sequence of data infinitely until you tell it to stop.

:rocket: Generator to Return Reddit Data

Here is a generator function that returns ReactJS subreddit data.

First thing to note is that, generators are declared with keyword function* (notice the star after the function keyword).

That * is what makes a function a generator .

On line#2, a URL is passed, with default value set to ReactJS API URL.

Line#4 shows a declaration of nextUrl , which is constructed using the url from line#2 and after argument required to fetch next batch of data (we will see it in a moment).

Now the while loop is where the interesting things happen.

nextUrl is empty initially so it’s set to url passed as a function argument.

Then we fetch Reddit data as JSON, which has a shape shown below.

Value stored in after property is what we need to fetch next batch of data.

And line #10 constructs the next URL to query to fetch more data.

nextUrl = `${url}&after=${json.data.after}`;

Thank you tills1993 for finding the bug in the previous code.

Now you see this unfamiliar keyword yield that returns an array of data using Array#map .

Yield temporarily returns the data and gives up the control to the calling code.

So when the calling code calls getContent again, all variables inside the while loop is restored thus nextUrl will contain the next URL not null .

( I am not sure if it’s the work of closures so I’d love to hear your feedback on it )

Lastly, we export getContent from ContentRepo.js .

We’ve covered how the generator function, getContent works so let’s move on to implement infinite scrolling in React.

:rocket: End Result

Before moving on, let’s see how the end result looks visually.

Infinite Scrolling in action

It loads 4 stories with “Load More Stories” button.

Infinite scrolling will happen when the page has stories that spans longer than the view port height.

Please pardon the color combinations, I tried my best to make it pretty…

Now you see how the end result looks, let’s move on.

:rocket: Implementing Infinite Scrolling

Let’s see the main component App’s structure.

App’s state contains all Reddit posts, and a flag to see if we have reached the bottom of the page.

repo is a generator that returns Reddit data infinitely as mentioned inGenerator to Return Reddit Data. getNextPosts returns next batch of Reddit posts (data fetch logic is hidden away in the generator function). windowsizeHandler is a callback that’s triggered when the browser window is resized or scrolled. componentDidMount is where we register Window Resize & Scroll events and get initial batch of Reddit posts. componentWillUnmount is where we unregister Resize & Scroll events to remove listeners. loadMoreStories is a helper function that’s called by Load More Stories button. render is where we load posts and shows Load More Stories button.

Let’s see the implementation of each method one by one.

:rocket: Component Implementation Details :moyai: componentDidMount

This is where we register two window events and fetch initial posts to display.

I’ve used lodash.throttle function to limit the number of events generated.

Or else there will be too many events fired and make too many Reddit API requests.

The reason for choosing throttle over debounce is because I wanted to load next batch of data without having to wait until user started/finished scrolling/resizing.

For the difference, refer to Debouncing and Throttling Explained Through Examples.

:moyai: componentWillUnmount

Make sure to clean up and free up listeners when the component is unmounted.

:moyai: windowSizeHandler

First we calculate whether we have reached the bottom of the viewport ( isBottomReached ).

window.scrollY is how much one has scrolled vertically so far window.innerHeight is the viewport height document.body.offsetHeight indicates the total height of the content in <body> .

If the sum of scrollY and innerHeight is same as document.bodyOffsetHeight , then we have reached the bottom.

An arbitrary heightOffset value is for fetching data before reaching the bottom

That means, users don’t have to wait for story to load after reaching the bottom.

Loading data before reaching bottom

:moyai: getNextPosts

We fetch next posts using the generator object instance, (await this.repo.next()).value .

:information_desk_person: Note that you don’t need to pass any arguments or keep a track of next URL to call. It’s completely abstracted away.

In line#4, new posts ( posts: [...prevState.posts, ...newPosts] ) are added

and turns off bottom flag since we just loaded new stories.

:moyai: render

Here we construct reddit posts and display Load More Stories button.

:moyai: loadMoreStories

getNextPosts is asynchronous so I wrapped it in an IIFE (Immediately Invoked Function Expression) as async rendering will be available in later version.

:moyai: RedditPost

Lastly, RedditPost component shows title and post content

:wave:Parting Words

JavaScript generator abstracted away all nitty gritty details on how to fetch data, and keep track of next URL to fetch from.

And make sure you either throttle or debounce windows scroll & resize events as they fire very rapidly as explained in this post, Debouncing and Throttling Explained Through Examples .


Infinite Scrolling in React using JavaScript Generator
Here is the link to the SandBox again.

I’ve also created a GitHub repository so you can clone it and play around with it locally.

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

tags: data,posts,next,function,Reddit,fetch
分页:12
转载请注明
本文标题:Infinite Scrolling in React using JavaScript Generator
本站链接:https://www.codesec.net/view/586899.html


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(46)