I'm trying to implement infinite scrolling on my react app for search hits from Algolia.
I came across a class component in their documentation. And I use React Hooks so tried to make it work on React Hooks. All I got was so many renders and my app gets hung up when this component mounts.
Here's my code:
import React, { useEffect, useRef } from 'react';
import Card from '@material-ui/core/Card';
import CardActionArea from '@material-ui/core/CardActionArea';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import Container from '@material-ui/core/Container';
import Grid from '@material-ui/core/Grid';
import { connectHits, connectInfiniteHits } from 'react-instantsearch-dom';
import noItemImage from './../../assets/img/noItemImage.png'
import { Link } from 'react-router-dom'
import ShareIcon from '@material-ui/icons/Share';
import PropTypes from 'prop-types';
function AlgoliaHits(props) {
const { hits } = props
console.log(hits)
var sentinel = useRef(null)
useEffect(() => {
function onSentinelIntersection (entries){
const { hasMore, refine } = props
entries.forEach(entry => {
if (entry.isIntersecting && hasMore) {
refine()
}
})
}
var observer = new IntersectionObserver(onSentinelIntersection, {})
observer.observe(sentinel.current)
return () => {
observer.disconnect()
}
}, [props])
return (
<Container maxWidth="md" style={{ marginBottom: 100 }}>
<Grid container spacing={2}>
{
hits.map(hit => (
<Grid item xs={12} sm={6} md={4} lg={4} xl={3}>
<Link to={`/item/${hit.item_id}`} style={{ textDecoration: 'none' }}>
<Card maxWidth={210} key={hit.item_id} elevation={0}>
<CardActionArea>
<CardMedia
component="img"
alt="Contemplative Reptile"
height="140"
image={
hit.item_images_url ?
hit.item_images_url.length === 0 ?
noItemImage
:
hit.item_images_url[0]
:
noItemImage
}
title={hit.item_name}
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2"
style={{ whiteSpace: 'nowrap', width: 250, overflow: 'hidden', textOverflow: 'ellipsis' }}>
{hit.item_name}
</Typography>
<Typography variant="body2" color="textSecondary" component="p"
style={{ whiteSpace: 'nowrap', width: 200, overflow: 'hidden', textOverflow: 'ellipsis' }}>
{hit.item_description}
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<Button size="small" color="primary" component={Link} to={`/item/${hit.item_id}`}>
View
</Button>
<IconButton size="small" color="secondary">
<ShareIcon style={{ padding: 4 }}/>
</IconButton>
</CardActions>
</Card>
</Link>
</Grid>
))
}
</Grid>
<div id="sentinel" ref={sentinel} />
</Container>
);
}
AlgoliaHits.propTypes = {
hits: PropTypes.arrayOf(PropTypes.object).isRequired,
hasMore: PropTypes.bool.isRequired,
refine: PropTypes.func.isRequired,
}
const AlgoliaInfiniteScroll = connectHits(AlgoliaHits)
const ItemCard = connectInfiniteHits(AlgoliaInfiniteScroll)
export default ItemCard
And here's where I used the reference from. What wrong am I doing? And how to solve it?
TIA