繁体   English   中英

Next.js 中的无限滚动在第一次获取时将最后一个元素加倍

[英]Infinite scroll in Next.js doubles the last element on first fetch

我有一个基于从 Strapi Rest API 获取的 Next.js 的项目。 我正在根据获取的内容获取和呈现卡片。 由于我不想一次加载所有内容,因此我使用react-infinite-scroller实现了无限滚动。 它工作正常,我唯一的问题是,根据元素的数量,有时,最后一个对象会再次返回,而不是下一页的第一个对象。 这只会在用户第一次到达页面底部时发生在无限加载器的第一次 fetch 调用中。

初始获取:

export async function getServerSideProps({locale}, ctx) {
    const jwt = parseCookies(ctx).jwt

    if (jwt) {
        const articlesArray = await getArticles({locale}, jwt, 0, 10)
        const articles = articlesArray.articlesList
        const total = articlesArray.total
        const cookieJwt = jwt
        return {

            props: {
                articles,
                cookieJwt,
                total


            },
        }
    }

    // I DELETED THE AUTH LOGIC HERE 

获取文章功能:

import qs from 'qs'

export async function getArticles({locale}, jwt,page, size) {
    const query = qs.stringify({
            pagination: {
                start: page,
                limit: size,
            },

            sort: ['date:desc'],
        },

        {
            encodeValuesOnly: true,
        });
    const fetchArticles = await fetch(`${process.env.DB_HOST}/api/articles?locale=${locale}&populate=*&${query}`,
        {
            headers: {

                Authorization: `Bearer ${jwt}`
            }
        })
    const articles = await fetchArticles.json()
    const articlesArray = {
        articlesList: articles.data ,
        total: articles.meta.pagination.total
    }


    return articlesArray
}
   

无限滚动组件:

  <InfiniteScroll
                    pageStart={0}
                    loadMore={getMorePost}
                    hasMore={hasMore}
                    loader={<div className={cardStyle.loaderWrapper}><div className={cardStyle.loader}><Loader color={'orange'} variant={'bars'} /></div></div>}

                >
                    <SimpleGrid cols={3}
                                spacing={"xl"}
                                breakpoints={[
                                    { maxWidth: 1200, cols: 2, spacing: 'md' },
                                    { maxWidth: 755, cols: 1, spacing: 'sm' },
                                ]}>

                        {posts.map((article) => {
                                return(
                                    <ArticleCard key={newKey()} data={article} locale={locale} onClick={() => handleClick(article)} />
                                )
                            }

                        )}

                    </SimpleGrid>
                </InfiniteScroll>    

获取更多帖子功能:

   const getMorePost = async () => {
 
        if(pageCounter < total){


            const res = await getArticles({locale},cookieJwt, pageCounter  , 10)
            setPageCounter(pageCounter + 10)


            const newPosts = res.articlesList;
            setPosts((post) => [...post, ...newPosts]);
        }
        else {
            setHasMore(false)



        }

    };

     

据我所知,应该加载前 10 个元素,而 getMorePost 应该加载接下来的 10 个元素。 然而,情况并非如此

可以在此处观察行为

完整页面可以在repo上找到

我认为可以使用 lodash 的_.uniqBy()方法( https://lodash.com/docs/4.17.15#uniqBy )来快速解决这个问题。 这将使您在第一次重新加载时总共显示 19 个,但它至少可以确保您没有任何重复的项目。

我认为真正的解决办法是弄清楚为什么 API 两次返回第 10 项; 尝试从数据库中获取原始查询时,似乎起始值可能不正确。

使用 burp 套件并使用代理拦截器,查询看起来像这样: /api/articles?locale=en&populate=*&pagination[start]=10&pagination[limit]=10&sort[0]=date%3Adesc . 我认为如果您将分页 [start] 提高 1,那实际上应该可以解决您的问题。 至少对我有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM