implemented infinite scroll

This commit is contained in:
Aria Moradi
2021-01-22 21:11:00 +03:30
parent 2c76ad9b74
commit 0757ea5d0d
7 changed files with 99 additions and 34 deletions
+7 -3
View File
@@ -38,8 +38,10 @@ const useStyles = makeStyles({
interface IProps {
manga: IManga
// eslint-disable-next-line react/no-unused-prop-types, react/require-default-props
// ref?: false | React.MutableRefObject<HTMLInputElement | undefined>
}
export default function MangaCard(props: IProps) {
const MangaCard = React.forwardRef((props: IProps, ref) => {
const {
manga: {
id, title, thumbnailUrl,
@@ -49,7 +51,7 @@ export default function MangaCard(props: IProps) {
return (
<Link to={`/manga/${id}/`}>
<Card className={classes.root}>
<Card className={classes.root} ref={ref}>
<CardActionArea>
<div className={classes.wrapper}>
<CardMedia
@@ -66,4 +68,6 @@ export default function MangaCard(props: IProps) {
</Card>
</Link>
);
}
});
export default MangaCard;
+39 -11
View File
@@ -1,26 +1,54 @@
import React from 'react';
import React, { useEffect, useRef } from 'react';
import MangaCard from './MangaCard';
interface IProps{
mangas: IManga[]
message?: string
hasNextPage: boolean
lastPageNum: number
setLastPageNum: (lastPageNum: number) => void
}
export default function MangaGrid(props: IProps) {
const { mangas, message } = props;
const {
mangas, message, hasNextPage, lastPageNum, setLastPageNum,
} = props;
let mapped;
const lastManga = useRef<HTMLInputElement>();
const scrollHandler = () => {
if (lastManga.current) {
const rect = lastManga.current.getBoundingClientRect();
if (((rect.y + rect.height) / window.innerHeight < 2) && hasNextPage) {
setLastPageNum(lastPageNum + 1);
}
}
};
useEffect(() => {
window.addEventListener('scroll', scrollHandler, true);
return () => {
window.removeEventListener('scroll', scrollHandler, true);
};
}, [hasNextPage, mangas]);
if (mangas.length === 0) {
mapped = <h3>{message !== undefined ? message : 'loading...'}</h3>;
mapped = <h3>{message}</h3>;
} else {
mapped = (
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(5, auto)', gridGap: '1em' }}>
{mangas.map((it) => (
<MangaCard manga={it} />
))}
</div>
);
mapped = mangas.map((it, idx) => {
if (idx === mangas.length - 1) {
return <MangaCard manga={it} ref={lastManga} />;
}
return <MangaCard manga={it} />;
});
}
return mapped;
return (
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(5, auto)', gridGap: '1em' }}>
{mapped}
</div>
);
}
MangaGrid.defaultProps = {
message: 'loading...',
};