Skip to content

Instantly share code, notes, and snippets.

@verdipratama
Last active October 23, 2021 19:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save verdipratama/77a69f31727845f20b0b3a84a2389d51 to your computer and use it in GitHub Desktop.
Save verdipratama/77a69f31727845f20b0b3a84a2389d51 to your computer and use it in GitHub Desktop.
React infinite scroll in few lines!
import React, { useEffect, useState, useRef } from 'react'
const divStyle = {
color: 'blue',
height: '250px',
textAlign: 'center',
padding: '5px 10px',
background: '#eee',
marginTop: '15px',
}
const containerStyle = {
maxWidth: '1280px',
margin: '0 auto',
}
export function InfiniteScroll() {
const [postList, setPostList] = useState({ list: [1, 2, 3, 4] })
// tracking on which page we currently are
const [page, setPage] = useState(1)
// add loader reference
const loader = useRef(null)
// here we handle what happens when user scrolls to Load More div
// in this case we just update page variable
const handleObserver = (entities) => {
const target = entities[0]
if (target.isIntersecting) {
setPage(_page => _page + 1)
}
}
useEffect(() => {
const options = {
root: null,
rootMargin: '20px',
threshold: 1.0,
}
// initialize IntersectionObserver and attaching to Load More div
const observer = new IntersectionObserver(handleObserver, options)
if (loader.current) {
observer.observe(loader.current)
}
}, [])
useEffect(() => {
// here we simulate adding new posts to List
const newList = postList.list.concat([1, 1, 1, 1])
setPostList({
list: newList,
})
}, [page, postList.list])
return (
<div className="container" style={containerStyle}>
<div className="post-list">
{postList.list.map((post, index) => (
<div key={index} className="post" style={divStyle}>
<h2>{post}</h2>
</div>
))}
<div className="loading" ref={loader}>
<h2>Load More</h2>
</div>
</div>
</div>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment