Intersection Observer not firing

I have a react app that displays a grid of 3 columns. I’m trying to implement the Intersection Observer Api to enable infinite scroll, however, it’s not working. The following code prints out:

false and ref is [object Object] and the elem is [object HTMLDivElement]
CarDisplay.tsx:307 IN THE RETURN
CarDisplay.tsx:309 unobserving?
CarDisplay.tsx:302 false and ref is [object Object] and the elem is [object HTMLDivElement]
CarDisplay.tsx:307 IN THE RETURN
CarDisplay.tsx:309 unobserving?
CarDisplay.tsx:302 true and ref is [object Object] and the elem is [object HTMLDivElement]

when the page loads, but doesn’t do anything else when I scroll. I want to hit hte callback when I get to the end of the ‘carDisplay’ element. I’ve played around with the threshold a bunch, but can’t get the observer to trigger.

export function CarDisplay() {
    const ref = useRef(null);
    const [isIntersecting, setIsIntersecting] = useState(false);
    const data = Array<ICarRequest>();

useEffect(() => {
  const observer = new IntersectionObserver(
    ([entry]) => {
      setIsIntersecting(entry.isIntersecting);          
    },
    { 
        threshold: .5
     }
  );
  if(ref && ref.current){
      console.log(`${isIntersecting} and ref is ${ref} and the elem is ${ref.current}`);
      observer.observe(ref.current);          
  }

    return () => {            
        if (ref.current) {
            console.log("unobserving?")
            observer.unobserve(ref.current);
        }
    }      
}, [isIntersecting]);

......

function getData(start: number, end:number){              
    if(data){
        const pageFilteredData = Array<ICarRequest>();            
        if(dropDownMakeText !== lastDropDownMakeText){                                
            const makeFilter = data.filter(x=> x.make == dropDownMakeText);            
            pageFilteredData.push(...makeFilter);            
        }            
        
        const finalData = pageFilteredData.length > 0 ? pageFilteredData :data;                           
        const somedata = finalData.slice(start,end).map(x=>         
        
        <Card>
            <Card.Img variant="top" src={x.thumbnail} />
            <Card.Body>
                <Card.Title>{x.year} {x.make} {x.model} {x.trim}</Card.Title>   
                <ListGroup>
                    <ListGroup.Item key={x.make + x.model + x.year + x.dealerPrice}>Dealer price: ${x.dealerPrice}</ListGroup.Item>
                    <ListGroup.Item key={x.make + x.model + x.year + x.msrp}>MSRP: ${x.msrp}</ListGroup.Item>
                    <ListGroup.Item key={x.make + x.model + x.year + x.driveTrain}>Drive Train: {x.driveTrain}</ListGroup.Item>
                </ListGroup>
            </Card.Body>
        </Card>            
        )          
        return somedata
    }
}

return (
    <Container className="container">
        <Container className="theContainer">
            <div id="carDisplay" ref={ref} className="row row-cols-3">                          
                {getData(startIndex, endIndex)}
            </div>
        </Container>
    </Container>
)

}

I’ve been able to get the observer to trigger if I double up the last Container, like:

<Container className="theContainer">
    <div id="carDisplay" ref={ref} className="row row-cols-3">                          
        {getData(startIndex, endIndex)}
    </div>
</Container>
<Container className="theContainer2">
    <div id="carDisplay2" ref={ref} className="row row-cols-3">                          
        {getData(startIndex, endIndex)}
    </div>
</Container>

If I do that, and scroll down and up the page, I can see the trigger firing, but I don’t completely understand why that’s happening.