index.tsx raw

   1  import { useEffect, useRef, useState } from 'react'
   2  import UserItem from '../UserItem'
   3  
   4  export default function ProfileList({ pubkeys }: { pubkeys: string[] }) {
   5    const [visiblePubkeys, setVisiblePubkeys] = useState<string[]>([])
   6    const bottomRef = useRef<HTMLDivElement>(null)
   7  
   8    useEffect(() => {
   9      setVisiblePubkeys(pubkeys.slice(0, 10))
  10    }, [pubkeys])
  11  
  12    useEffect(() => {
  13      const options = {
  14        root: null,
  15        rootMargin: '10px',
  16        threshold: 1
  17      }
  18  
  19      const observerInstance = new IntersectionObserver((entries) => {
  20        if (entries[0].isIntersecting && pubkeys.length > visiblePubkeys.length) {
  21          setVisiblePubkeys((prev) => [...prev, ...pubkeys.slice(prev.length, prev.length + 10)])
  22        }
  23      }, options)
  24  
  25      const currentBottomRef = bottomRef.current
  26      if (currentBottomRef) {
  27        observerInstance.observe(currentBottomRef)
  28      }
  29  
  30      return () => {
  31        if (observerInstance && currentBottomRef) {
  32          observerInstance.unobserve(currentBottomRef)
  33        }
  34      }
  35    }, [visiblePubkeys, pubkeys])
  36  
  37    return (
  38      <div className="px-4 pt-2">
  39        {visiblePubkeys.map((pubkey, index) => (
  40          <UserItem key={`${index}-${pubkey}`} userId={pubkey} />
  41        ))}
  42        {pubkeys.length > visiblePubkeys.length && <div ref={bottomRef} />}
  43      </div>
  44    )
  45  }
  46