Duplicate data is repeating in infinite scroll in react.js

32 Views Asked by At

I'm currently working on implementing infinite scrolling functionality without relying on any external packages. However, I'm encountering an issue where the data is repeating. I'm using JSON Server for my backend, but interestingly, when I switch to using the 'https://jsonplaceholder.typicode.com/comments' API, the infinite scroll works fine without any data repetition. Could you please help me troubleshoot and resolve this issue? Thank you!

import React, { useState, useEffect } from 'react';
import axios from 'axios';

const InfiniteScrolling = () => {
    const [data, setData] = useState([]);
    const [loading, setLoading] = useState(false);
    const [page, setPage] = useState(1);
    const [allDataLoaded, setAllDataLoaded] = useState(false);
    const limit = 3;

    useEffect(() => {
        fetchData();
    }, []);

    const fetchData = async () => {
        if (loading || allDataLoaded) return;
        setLoading(true);
        try {
            const response = await axios.get(`http://localhost:3000/posts?_page=${page}&_limit=${limit}`);
            setData([...data, ...response.data]);
            setPage(prevPage => prevPage + 1);
            if (response.data.length < limit) {
                setAllDataLoaded(true);
            }
        } catch (error) {
            console.error('Error fetching data:', error);
        } finally {
            setLoading(false);
        }
    };

    const handleScroll = () => {
        if (loading || allDataLoaded) return;
        const scrollTop = document.documentElement.scrollTop;
        const windowHeight = window.innerHeight;
        const scrollHeight = document.documentElement.scrollHeight;

        if (scrollTop + windowHeight >= scrollHeight - 10) {
            fetchData();
        }
    };

    useEffect(() => {
        window.addEventListener('scroll', handleScroll);
        return () => window.removeEventListener('scroll', handleScroll);
    }, [loading, allDataLoaded]);

    function createMarkup(text) {
        return { __html: text };
    };

    return (
        <>
            <div className="container">
                {data.map((value, ind) => (
                    <div className='grid-container mb-3 data_widget' key={ind}>
                        <div className='grid-item'>
                            <img src={value.urlToImage || 'images/default_img.png'} className='img-fluid' alt={value.title} />
                        </div>
                        <div className='grid-item'>
                            <h5 className="heading_title d-inline">{value.profilename}</h5> <small>{value.publishedAt}</small>
                            <div className="body_widget">
                                <div className="card_white p-3 mt-2">
                                    <div className="card-body">
                                        <div className="card-text" dangerouslySetInnerHTML={createMarkup(value.description)} id={'blog_content_' + value.id}>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                ))}
                {loading && <p>Loading...</p>}
                {allDataLoaded && <p>All data loaded</p>}
            </div>
        </>
    );
};

export default InfiniteScrolling;
1

There are 1 best solutions below

0
Muhammad Adil On

It seems your issue might be related to state updates or how the backend handles pagination. Try these steps to resolve the data repetition in your infinite scroll implementation.

  1. Use a unique identifier from your data as the key (e.g key={value.id}) instead of the array index.
  2. Make sure your backend properly processes _page and _limit parameters to return distinct sets of data for each query, avoiding any data overlap.

setData(currentData => [...currentData, ...response.data]); setPage(currentPage => currentPage + 1);

Update your state like this to append new data and advance the page number, ensuring updates are based on the latest state.

I hope implementing these steps will help you fix the issue with data repetition in your infinite scroll functionality.