4

I have implemented infinite scroll on React.js Here is my infinite scroll component which is working fine.

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;
And here is my function where I making request for getting more data

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]
            })
        })
    }

When I delete an item I just delete this item from state by id. It is working, but the problem is when I create new item, I need to update list of items. What is the best way to do that? On the server I have a pagination and getting a list as {data:[], current_page:1, last_page:3, total_items:20} I can push new item in state. But how to avoid duplicates of the same item?

Maxim
  • 68
  • 1
  • 7

2 Answers2

1

If you know where in the array it needs to be added you can just update state pretty similar to what you were doing when fetching data

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

If you are adding to the top and your server is returning the same item again you can try and use the same key prop for both items. If they both have the same key React won't render them twice

Jonathan Irwin
  • 5,009
  • 2
  • 29
  • 48
1

You can update your loadMoreResources function like that to remove all duplicates from the state.

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]
            })
        })
    }
Ann
  • 772
  • 1
  • 9
  • 17