I´m using the dependency react-infinite-scroll-hook in the functional component below, where I do retrieve data from PokéAPI. However, the data is only loaded the first time the function loadData
is called in useEffect
, but scrolling to the component with sentryRef
does not trigger onLoadMore
in useInfiniteScroll
. What I'm missing here?
import React, { useState, useEffect } from 'react';
import { Grid, CircularProgress, capitalize, List, ListItem, ListItemIcon, ListItemText } from '@material-ui/core';
import useInfiniteScroll from 'react-infinite-scroll-hook';
import axios from 'axios';
import { Lens } from '@material-ui/icons';
function NationalPokedex(props) {
const [pokemons, setPokemons] = useState([]);
const [loading, setLoading] = useState(false);
const [hasNext, setHasNext] = useState(true);
const [next, setNext] = useState('https://pokeapi.co/api/v2/pokemon/');
const loadData = () => {
setLoading(true);
console.log("FETCH")
axios.get(next).then(response => {
setPokemons([...pokemons, ...response.data.results]);
if(response.data.next) {
setNext(response.data.next);
} else {
setHasNext(false);
setNext(null);
}
setLoading(false);
});
}
const [sentryRef] = useInfiniteScroll({
loading,
hasNext,
onLoadMore: loadData,
disabled: !!hasNext,
rootMargin: '0px 0px 100px 0px',
});
useEffect(loadData, []);
const renderData = () => {
var result = [];
pokemons.map((pokemon) => {
result.push(<ListItem key={pokemon.name}><ListItemIcon><Lens></Lens></ListItemIcon><ListItemText>{capitalize(pokemon.name)}</ListItemText></ListItem>);
});
console.log("LOAD_DATA");
console.log(hasNext, next, loading, pokemons);
return result;
}
return (
<>
<List spacing={3}>
{renderData()}
</List>
{(hasNext || loading) && (
<Grid container item xs={12} ref={sentryRef} justifyContent='center' key='progress'>
<CircularProgress/>
</Grid>
)}
</>
);
}
I ended up using another dependency, react-infinite-scroller
, that works perfectly, so I guess the issue was not on my side.
The code looks like this, in case it is useful for someone:
import React, { useState } from 'react';
import { Grid, CircularProgress, capitalize, List, ListItem, ListItemIcon, ListItemText } from '@material-ui/core';
import InfiniteScroll from 'react-infinite-scroller';
import axios from 'axios';
import { Lens } from '@material-ui/icons';
function NationalPokedex(props) {
const [pokemons, setPokemons] = useState([]);
const [hasNext, setHasNext] = useState(true);
const [next, setNext] = useState('https://pokeapi.co/api/v2/pokemon/');
const loadData = () => {
axios.get(next).then(response => {
setPokemons([...pokemons, ...response.data.results]);
if(response.data.next) {
setNext(response.data.next);
} else {
setHasNext(false);
setNext(null);
}
});
}
const renderData = () => {
var result = [];
pokemons.map((pokemon) => {
result.push(<ListItem key={pokemon.name}><ListItemIcon><Lens></Lens></ListItemIcon><ListItemText>{capitalize(pokemon.name)}</ListItemText></ListItem>);
});
return result;
}
return (
<InfiniteScroll
pageStart={0}
loadMore={loadData}
hasMore={hasNext}
loader={<Grid container item xs={12} justifyContent='center' key='progress'><CircularProgress/></Grid>}
threshold={0}
>
<List>{renderData()}</List>
</InfiniteScroll>
);
}
export default NationalPokedex;