I'm trying to load the second set of items from the reddit API with Infinite scrolling when the user scrolls to the bottom of the page and although they do load successfully, the previous items are overridden by the new ones.
You can see this happening here: https://reddix.netlify.app/
This is the Redux Slice with the Thunks:
// Gets the first 10 Posts from the API
export const getPosts = createAsyncThunk(
"post/getPosts",
async (apiAddress) => {
const response = await fetch(apiAddress);
if (!response.ok) throw new Error("Request Failed!");
const data = await response.json();
return data;
}
);
// Loads the Next 10 Posts
export const getMorePosts = createAsyncThunk(
"post/getMorePosts",
async (apiAddress) => {
const response = await fetch(apiAddress);
if (!response.ok) throw new Error("Request Failed!");
const data = await response.json();
return data;
}
);
const redditPostSlice = createSlice({
name: "post",
initialState: {
redditPost: {},
isLoading: false,
hasError: false,
moreIsLoading: false,
moreHasError: false,
},
extraReducers: (builder) => {
builder
.addCase(getPosts.pending, (state) => {
state.isLoading = true;
state.hasError = false;
})
.addCase(getPosts.fulfilled, (state, action) => {
state.redditPost = action.payload.data;
state.isLoading = false;
state.hasError = false;
})
.addCase(getPosts.rejected, (state) => {
state.isLoading = false;
state.hasError = true;
})
.addCase(getMorePosts.pending, (state) => {
state.moreIsLoading = true;
state.moreHasError = false;
})
.addCase(getMorePosts.fulfilled, (state, action) => {
state.redditPost = action.payload.data;
state.moreIsLoading = false;
state.moreHasError = false;
})
.addCase(getMorePosts.rejected, (state) => {
state.moreIsLoading = false;
state.moreHasError = true;
});
},
});
And in this Search components I have the functionality for loading the pages:
const Search = () => {
const [input, setInput] = useState("");
const [isFetching, setIsFetching] = useState(false);
const redditPost = useSelector(selectRedditPost);
const dispatch = useDispatch();
// Get the Last Post
const lastPost = () => {
if (redditPost.children) {
const [lastItem] = redditPost.children.slice(-1);
const lastKind = lastItem.kind;
const lastId = lastItem.data.id;
return `${lastKind}_${lastId}`;
} else {
return;
}
};
// API Endpoints
const hotApiAddress = `https://www.reddit.com/r/${input}/hot.json?limit=10`;
const newApiAddress = `https://www.reddit.com/r/${input}/new.json?limit=10`;
const moreApiAddress = `https://www.reddit.com/r/${input}/new.json?limit=10&after=${lastPost()}`;
// Get Hot Posts
const handleHot = (e) => {
e.preventDefault();
if (!input) return;
dispatch(getPosts(hotApiAddress));
};
// Get New Posts
const handleNew = (e) => {
e.preventDefault();
if (!input) return;
dispatch(getPosts(newApiAddress));
};
// Fire Upon Reaching the Bottom of the Page
const handleScroll = () => {
if (
window.innerHeight + document.documentElement.scrollTop !==
document.documentElement.offsetHeight
)
return;
setIsFetching(true);
};
// Debounce the Scroll Event Function and Cancel it When Called
const debounceHandleScroll = debounce(handleScroll, 100);
useEffect(() => {
window.addEventListener("scroll", debounceHandleScroll);
return () => window.removeEventListener("scroll", debounceHandleScroll);
}, [debounceHandleScroll]);
debounceHandleScroll.cancel();
// Get More Posts
const loadMoreItems = useCallback(() => {
dispatch(getMorePosts(moreApiAddress));
setIsFetching(false);
}, [dispatch, moreApiAddress]);
useEffect(() => {
if (!isFetching) return;
loadMoreItems();
}, [isFetching, loadMoreItems]);
Is there any way to keep the previous items when the next set loads?