Skip to content

Instantly share code, notes, and snippets.

@msell
Created April 4, 2025 00:30
Show Gist options
  • Save msell/5c441dbe19f016bbad0bacb38f6316df to your computer and use it in GitHub Desktop.
Save msell/5c441dbe19f016bbad0bacb38f6316df to your computer and use it in GitHub Desktop.
import './App.css';
import useInfiniteScroll from './useInfiniteScroll';
import { useState, useEffect } from 'react';
const PAGE_SIZE = 10;
const fetchPosts = async (page: number) => {
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts?_page=${page}&_limit=${PAGE_SIZE}`
);
return response.json();
};
function App() {
const [posts, setPosts] = useState<any[]>([]);
const [page, setPage] = useState(1);
const [hasMore, setHasMore] = useState(true);
const [loading, setLoading] = useState(false);
const loadMore = async () => {
if (loading) return;
setLoading(true);
const newPosts = await fetchPosts(page);
setPosts((prev) => [...prev, ...newPosts]);
setPage((prev) => prev + 1);
setLoading(false);
// JSONPlaceholder only has 100 posts, so stop after page 10
if (page >= 10) setHasMore(false);
};
const lastItemRef = useInfiniteScroll(loadMore, hasMore);
useEffect(() => {
loadMore(); // Fetch initial data
}, []);
return (
<div>
<h2>Infinite Scroll with JSONPlaceholder</h2>
{posts.map((post, index) => (
<div
key={crypto.randomUUID()}
ref={index === posts.length - 1 ? lastItemRef : null}
style={{ padding: 10, border: '1px solid black', marginBottom: 5 }}
>
<h4>{post.title}</h4>
<p>{post.body}</p>
</div>
))}
{loading && <p>Loading more posts...</p>}
{!hasMore && <p>No more posts available</p>}
</div>
);
}
export default App;
import './App.css';
import useInfiniteScroll from './useInfiniteScroll';
import { useState, useEffect } from 'react';
const PAGE_SIZE = 10;
const fetchPosts = async (page: number) => {
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts?_page=${page}&_limit=${PAGE_SIZE}`
);
return response.json();
};
function App() {
const [posts, setPosts] = useState<any[]>([]);
const [page, setPage] = useState(1);
const [hasMore, setHasMore] = useState(true);
const [loading, setLoading] = useState(false);
const loadMore = async () => {
if (loading) return;
setLoading(true);
const newPosts = await fetchPosts(page);
setPosts((prev) => [...prev, ...newPosts]);
setPage((prev) => prev + 1);
setLoading(false);
// JSONPlaceholder only has 100 posts, so stop after page 10
if (page >= 10) setHasMore(false);
};
const lastItemRef = useInfiniteScroll(loadMore, hasMore);
useEffect(() => {
loadMore(); // Fetch initial data
}, []);
return (
<div>
<h2>Infinite Scroll with JSONPlaceholder</h2>
{posts.map((post, index) => (
<div
key={crypto.randomUUID()}
ref={index === posts.length - 1 ? lastItemRef : null}
style={{ padding: 10, border: '1px solid black', marginBottom: 5 }}
>
<h4>{post.title}</h4>
<p>{post.body}</p>
</div>
))}
{loading && <p>Loading more posts...</p>}
{!hasMore && <p>No more posts available</p>}
</div>
);
}
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment