Reputation: 95
I am trying to take a tutorial for an infinite scroll using vanilla javascript and use react. To get a better understanding of how react works. I can fetch the data display the initial data. Scroll to the bottom fetch more data but the data just over riders the current data. Also I can only fetch up to page 2 I would love if someone could point me in the right direction.
import React, { useState, useEffect } from "react";
import "./App.css";
function App() {
const [posts, setPosts] = useState([{}]);
const [isFetching, setIsFetching] = useState(false);
let limit = 5;
let page = 1;
const getPosts = async () => {
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts?_limit=${limit}&_page=${page}`
);
const data = await response.json();
setPosts(data);
console.log(data);
};
function handleScroll() {
if (
window.innerHeight + document.documentElement.scrollTop !==
document.documentElement.offsetHeight
)
return;
setIsFetching(true);
}
function getMorePosts() {
setTimeout(() => {
page++;
setPosts([{ ...posts }], posts);
setIsFetching(false);
}, 2000);
}
useEffect(() => {
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
useEffect(
() => {
getPosts();
}, //eslint-disable-next-line
[]
);
useEffect(() => {
if (!isFetching) return;
getMorePosts();
}, [isFetching]);
return (
<div className="App">
{posts.map((post, index) => (
<div key={index} className="post">
<div className="number">{post.id}</div>
<div className="post-info">
<h2 className="post-title">{post.title}</h2>
<p className="post-body">{post.body}</p>
</div>
</div>
))}
{isFetching && (
<div className="loader">
<div className="circle"></div>
<div className="circle"></div>
<div className="circle"></div>
</div>
)}
</div>
);
}
export default App;
Upvotes: 3
Views: 13199
Reputation: 9825
One thing I noticed off the bat is that page
is not in the state so it will be reset on every render. Also since limit
is not changing you should use a constant.
Why are you initializing this to an array with an empty object in it? useState([{}]);
just use an empty array
Also I'm not sure what you are intending to do here setPosts([{ ...posts }], posts);
but if you want to append the new posts while copying the objects you should do this
const getPosts = async () => {
setIsFetching(true)
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts?_limit=${limit}&_page=${page}`
);
const data = await response.json();
setPosts([...posts, ...data]);
setIsFetching(false)
};
function getMorePosts() {
setTimeout(() => {
setPage(page++)
getPosts();
}, 2000);
}
Upvotes: 4