OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

State in IntersectionObserver callback is undefined

  • Thread starter Thread starter ygetarts
  • Start date Start date
Y

ygetarts

Guest
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:

Code:
in handleObserver
TestStateUpdater2.tsx:168 this is data  undefined

and my current code:

Code:
export function TestStateUpdater2() {
    const [data, setData] = useState<Array<ICarRequest>>()
    const ref = useRef(null);    

    useEffect(()=> {
        setData([
            {
                priceMax: 1, 
                newOrUsed:"new", 
                make: "make",
                model: "model",
                year: 222,
                bodyType: "jeep",
                fuelType: "gas",
                color: "blue",
                thumbnail: "picture",
                trim: "nice",
                dealerPrice: "333",
                msrp: 345,
                driveTrain: "5"
            },
    .....
        ])        
    }, [])

    useEffect(() => {        
        const observer = new IntersectionObserver(
        handleObserver,
        { 
            threshold: []
            }
        );
        if(ref && ref.current){        
            observer.observe(ref.current);          
        }      

        return () => {            
            if (ref.current) {                
                observer.unobserve(ref.current);
            }
        }                
    }, []);

    function handleObserver(x: IntersectionObserverEntry[]){        
        console.log("in handleObserver")
        console.log("this is data ", data)        
        const newArray = [
            {
                priceMax: 1, 
                newOrUsed:"new", 
                make: "make",
                model: "model",
                year: 222,
                bodyType: "jeep",
                fuelType: "gas",
                color: "blue",
                thumbnail: "picture",
                trim: "nice",
                dealerPrice: "333",
                msrp: 345,
                driveTrain: "5"
            }
        ];
        // if(data)
        //     setData([...data,...newArray]);
    }


    function getData(){                
        if(data){                            
            const somedata = data.slice(0,10).map(x=>         
            <div>
            <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>
            </div>    
            )          
            return somedata
        }
    }

    return (
        <Container className="container">
            <Container className="theContainer">
                <div id="carDisplay" ref={ref} className="row row-cols-3">                          
                    {getData()}
                </div>
            </Container>
            <Container className="theContainer2">
                <div  ref={ref} className="footer">     
                    This is a footer
                </div>
            </Container>
        </Container>
    )
  }

When I scroll, the Observer triggers, but what's in state is undefined. I want the handleObserver method to trigger, where I plan on making another api call to add to 'data'. I don't understand why 'data' is undefined in the callback? If I change the useEffect that creates the Observer to

Code:
        const observer = new IntersectionObserver(
        handleObserver,
......
    }, [data]);

now, the 'data' in handleObserver has values and is no longer undefined. But, if I go ahead and update 'data' there:

Code:
       if(data)
          setData([...data,...newArray]);

it sets off an infinite loop. I'm not sure what I'm supposed to do? I want to scroll down on the page, have the Observer trigger the handleObserver callback, then load in more items to my grid.

<p>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:</p>
<pre><code>in handleObserver
TestStateUpdater2.tsx:168 this is data undefined
</code></pre>
<p>and my current code:</p>
<pre><code>export function TestStateUpdater2() {
const [data, setData] = useState<Array<ICarRequest>>()
const ref = useRef(null);

useEffect(()=> {
setData([
{
priceMax: 1,
newOrUsed:"new",
make: "make",
model: "model",
year: 222,
bodyType: "jeep",
fuelType: "gas",
color: "blue",
thumbnail: "picture",
trim: "nice",
dealerPrice: "333",
msrp: 345,
driveTrain: "5"
},
.....
])
}, [])

useEffect(() => {
const observer = new IntersectionObserver(
handleObserver,
{
threshold: []
}
);
if(ref && ref.current){
observer.observe(ref.current);
}

return () => {
if (ref.current) {
observer.unobserve(ref.current);
}
}
}, []);

function handleObserver(x: IntersectionObserverEntry[]){
console.log("in handleObserver")
console.log("this is data ", data)
const newArray = [
{
priceMax: 1,
newOrUsed:"new",
make: "make",
model: "model",
year: 222,
bodyType: "jeep",
fuelType: "gas",
color: "blue",
thumbnail: "picture",
trim: "nice",
dealerPrice: "333",
msrp: 345,
driveTrain: "5"
}
];
// if(data)
// setData([...data,...newArray]);
}


function getData(){
if(data){
const somedata = data.slice(0,10).map(x=>
<div>
<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>
</div>
)
return somedata
}
}

return (
<Container className="container">
<Container className="theContainer">
<div id="carDisplay" ref={ref} className="row row-cols-3">
{getData()}
</div>
</Container>
<Container className="theContainer2">
<div ref={ref} className="footer">
This is a footer
</div>
</Container>
</Container>
)
}
</code></pre>
<p>When I scroll, the Observer triggers, but what's in state is undefined. I want the handleObserver method to trigger, where I plan on making another api call to add to 'data'. I don't understand why 'data' is undefined in the callback?
If I change the useEffect that creates the Observer to</p>
<pre><code> const observer = new IntersectionObserver(
handleObserver,
......
}, [data]);
</code></pre>
<p>now, the 'data' in handleObserver has values and is no longer undefined. But, if I go ahead and update 'data' there:</p>
<pre><code> if(data)
setData([...data,...newArray]);
</code></pre>
<p>it sets off an infinite loop.
I'm not sure what I'm supposed to do? I want to scroll down on the page, have the Observer trigger the handleObserver callback, then load in more items to my grid.</p>
 

Latest posts

Online statistics

Members online
0
Guests online
4
Total visitors
4
Top