添加新项目时如何使用无限滚动更新项目列表

How to update list of items with Infinite scroll when new item added

我在 React.js 上实现了无限滚动 这是我的无限滚动组件,它工作正常。

import React, {useRef,useCallback} from 'react';

function InfiniteScrollContainer(props) {
    let {children,loadMore,hasMoreItems,classes} = props;

    const observer = useRef()
    const bottomRef = useCallback(node => {
        if (observer.current) observer.current.disconnect()
        observer.current = new IntersectionObserver(entries => {
            if (entries[0].isIntersecting && hasMoreItems) {
                loadMore()
            }
        })
        if (node) observer.current.observe(node)
    }, [hasMoreItems, loadMore]);


    return(
        <div>
            <div className={classes}>
                {children}
            </div>
            {hasMoreItems && <div className="load-more__container" ref={bottomRef}>
                <span>Loading</span>
                <div className="load-more-anim">
                    <div className="circle"/>
                    <div className="circle"/>
                    <div className="circle"/>
                </div>
            </div>}
            {!hasMoreItems && <div className="load-more__container">No more data</div>}
        </div>
    )
}

export default InfiniteScrollContainer;
这是我的功能,我在其中请求获取更多数据

loadMoreResources = () => {
        let {page,resources} = this.state;
        let newPage = page +1;
        this.setState({page: newPage})
        this.props.getResources(undefined,undefined,newPage).then((res) => {
            if(res.meta && (res.meta.current_page < res.meta.last_page)){
                this.setState({hasMoreItems:true})
            }else this.setState({hasMoreItems:false})
            this.setState({
                resources: [...resources,...res.data]
            })
        })
    }

当我删除一个项目时,我只是通过 ID 从状态中删除了这个项目。它正在工作,但问题是当我创建新项目时,我需要更新项目列表。最好的方法是什么? 在服务器上我有一个分页并得到一个列表 {data:[], current_page:1, last_page:3, total_items:20} 我可以在状态下推送新项目。但是如何避免相同项目的重复?

如果您知道需要将它添加到数组中的什么位置,您可以更新状态,这与您在获取数据时所做的非常相似

this.setState({
  resources: [newItem,...this.state.resources]
})

如果您要添加到顶部并且您的服务器再次返回相同的项目,您可以尝试对这两个项目使用相同的 key prop。如果它们都有相同的键,React 将不会渲染它们两次

您可以像这样更新 loadMoreResources 函数以从状态中删除所有重复项。

loadMoreResources = () => {
        let {page,resources} = this.state;
        let newPage = page +1;
        this.setState({page: newPage})
        this.props.getResources(undefined,undefined,newPage).then((res) => {
            let ids = res.data.map(o => o.id)
            let stateWithoutDuplicates = resources.filter(({id}) => !ids.includes(id))
            if(res.meta && (res.meta.current_page < res.meta.last_page)){
                this.setState({hasMoreItems:true})
            }else this.setState({hasMoreItems:false})
            this.setState({
                resources: [...stateWithoutDuplicates,...res.data]
            })
        })
    }