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.