I am making the infinite scroll in react js , but i am having problem setting the posts value whenever i refresh the page the posts length is 0 whereas it should have been 10.
But after the first reload if i don't reload and just change something in code ( lets say add console.log ) and save it then the whole infinite scroll starts working but if i reload then it stops working
Please help.
Feed.js
import { Box, CircularProgress, Stack, Typography } from "@mui/material";
import Post from "./Post";
import About from "./About";
import { useEffect, useRef, useState } from "react";
import { getInfiniteScroll } from "../apis/posts";
import { useNavigate } from "react-router-dom";
const Feed = () => {
// const posts = useSelector((state) => state.allPosts.posts);
const [posts, setPosts] = useState([]);
const [skip, setSkip] = useState(0);
const [isEnd, setIsEnd] = useState(false);
const ref = useRef();
useEffect(() => {
fetchPosts();
ref.current?.addEventListener("scroll", handleScroll);
// return () => ref.current?.removeEventListener("scroll", handleScroll);
}, [skip]);
const fetchPosts = async () => {
try {
const { data, error } = await getInfiniteScroll(skip);
if (error) {
console.log(error);
return;
}
if (data?.length === 0) {
setIsEnd(true);
return;
}
// setPosts(data);
setPosts([...posts, ...data]);
console.log(posts.length);
} catch (error) {
console.log(error.message);
}
};
const handleScroll = (e) => {
const { offsetHeight, scrollTop, scrollHeight } = e.target;
if (offsetHeight + scrollTop >= scrollHeight) {
console.log(posts?.length);
setSkip(posts?.length);
}
console.log("skip : ", skip);
};
return (
<Box flex={4} sx={{ padding: { xs: "0", sm: "0px 20px " } }}>
<Box
ref={ref}
// onScroll={handleScroll}
sx={{
width: { xs: "100%", sm: "105% " },
marginBottom: "50px",
height: "600px",
overflow: "scroll",
overflowX: "hidden",
}}>
{posts.length > 0 ? (
posts.map((post) => <Post key={post._id} {...post} />)
) : (
<Box
sx={{
display: "flex",
justifyContent: "center",
alignSelf: "center",
marginTop: "200px",
}}>
<CircularProgress
sx={{
alignSelf: "center",
}}
/>
</Box>
)}
</Box>
<Box
sx={{
display: { sm: "none", xs: "block" },
justifyContent: "center",
alignItems: "center",
paddingBottom: "50px",
}}>
<About />
</Box>
</Box>
);
};
export default Feed;
Posts.js
import {
Avatar,
Card,
CardActions,
CardContent,
CardHeader,
CardMedia,
Checkbox,
IconButton,
} from "@mui/material";
import ShareIcon from "@mui/icons-material/Share";
import MoreVertIcon from "@mui/icons-material/MoreVert";
import Favorite from "@mui/icons-material/Favorite";
import { FavoriteBorder } from "@mui/icons-material";
import { useNavigate } from "react-router-dom";
import SmartText from "../Helpers/SmartText";
import { capitalize } from "../Helpers/Capitalize";
const Post = ({ _id, desc, title, photo, caption, updatedAt }) => {
const navigate = useNavigate();
return (
<Card sx={{ marginBottom: "20px" }}>
<CardHeader
avatar={
<Avatar sx={{ bgcolor: "red" }} aria-label="recipe">
{Array.from(title)[0]}
</Avatar>
}
action={
<IconButton aria-label="settings">
<MoreVertIcon />
</IconButton>
}
title={capitalize(title)}
subheader={updatedAt}
onClick={() => {
navigate("/posts/singlePost/" + _id);
}}
sx={{ cursor: "pointer" }}
/>
<CardMedia component="img" height="20%" image={photo} alt="Paella dish" />
<CardContent>
<SmartText text={desc} />
{/* <Typography variant="body2" color="text.secondary">
{post.desc}
</Typography> */}
</CardContent>
<CardActions disableSpacing>
<IconButton aria-label="add to favorites">
<Checkbox
icon={<FavoriteBorder />}
checkedIcon={<Favorite sx={{ color: "red" }} />}
/>
</IconButton>
<IconButton aria-label="share">
<ShareIcon />
</IconButton>
{/* <ExpandMore
expand={expanded}
aria-expanded={expanded}
aria-label="show more"
>
<ExpandMoreIcon />
</ExpandMore> */}
</CardActions>
</Card>
);
};
export default Post;
api/posts.js
export const getInfiniteScroll = async (skip) => {
try {
const res = await fetch(`/api/posts/infiniteScroll?skip=${skip}`, {
method: "GET",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
});
return await res.json();
} catch (error) {
throw new Error(error);
}
};
backend/postController.js
exports.getInfinitePost = async (req, res) => {
const skip = req.query.skip ? Number(req.query.skip) : 0;
const DEFAULT_LIMIT = 10;
try {
const posts = await Post.find({}).skip(skip).limit(DEFAULT_LIMIT);
res.status(201).json({ data: posts, success: true });
} catch (error) {
res.status(400).json({ message: error });
}
};