무한스크롤 구현하기
- test UI
- 더미 데이터는 https://jsonplaceholder.typicode.com/comments에서 가져왔다. 포스터는 images폴더에 따로 넣어놓았다.
Scroll
// Scroll.tsx
import React, { useEffect, useState } from "react";
import InfiniteScroll from "react-infinite-scroll-component";
import "./Scroll.scss";
import Poster from "./Poster";
import Loader from "./Loader";
import EndMessage from "./EndMessage";
function Scroll() {
const [items, setItems] = useState([]);
// 끝까지 갈 경우 페이지를 더이상 불러오지 않도록 설정
const [hasMore, setHasMore] = useState(true);
const [page, setPage] = useState(2);
useEffect(() => {
const getComments = async () => {
const res = await fetch(
`https://jsonplaceholder.typicode.com/comments?_page=1&_limit=20`
);
const data = await res.json();
setItems(data);
};
getComments();
}, []);
const fetchComments = async () => {
const res = await fetch(
`https://jsonplaceholder.typicode.com/comments?_page=${page}&_limit=20`
);
const data = await res.json();
return data;
};
// fetchData : 화면이 아래까지 도착함을 감지할 경우 다음 페이지를 불러옴
const fetchData = async () => {
const commentsFormServer = await fetchComments();
setItems([...items, ...commentsFormServer]);
// 페이지를 끝까지 불러왔는지 확인
if (commentsFormServer.length === 0 || commentsFormServer.length < 20) {
// 화면이 끝까지 불러올 경우 false로 변경하여 더이상 불러오지 않음
setHasMore(false);
}
setPage(page + 1);
};
return (
<div id="scroll">
<InfiniteScroll
className="infinitescroll"
dataLength={items.length}
next={fetchData}
hasMore={hasMore}
loader={<Loader className="scroll-loader" />}
endMessage={<EndMessage />}
>
<div className="scroll">
{items.map(item => {
return <Poster key={item.id} item={item} />;
})}
</div>
</InfiniteScroll>
</div>
);
}
export default Scroll;
- Loader는 처음에 Material UI 컴포넌트를 사용했으나 오류가 있어 제거했다.
// Loader.tsx
import * as React from "react";
function Loader() {
return (
<div>
<h3>Now Loading...</h3>
</div>
);
}
export default Loader;
// EndMessage.tsx
import React from "react";
function EndMessage() {
return (
<div>
<p style={{ textAlign: "center", color: "white" }}>
<b>End Contents</b>
</p>
</div>
);
}
export default EndMessage;
/* Scroll.scss */
#scroll {
overflow-y: hidden;
.infinitescroll {
overflow-y: hidden;
}
.scroll {
width: 1000px;
display: grid;
grid-template-columns: repeat(4, 1fr);
justify-items: center;
}
}
.infinite-scroll-component {
overflow-y: hidden;
}
Poster
- Poster는 Material UI를 활용했다.
// Poster.jsx
import * as React from "react";
import Card from "@mui/material/Card";
import CardContent from "@mui/material/CardContent";
import CardMedia from "@mui/material/CardMedia";
import Typography from "@mui/material/Typography";
import posterSample from "assets/images/posterSample.png";
/* eslint-disable react/prop-types */
function Poster({ item: { id, email, body } }) {
return (
<Card id="card" sx={{ width: 200, height: 500, padding: 0, marginTop: 3 }}>
<CardMedia
component="img"
height="200"
image={posterSample}
alt="green iguana"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="div">
{id}
</Typography>
<Typography variant="body2" color="text.secondary">
{email}
<br />
{body}
</Typography>
</CardContent>
</Card>
);
}
export default Poster;
'React' 카테고리의 다른 글
[React] React Slick을 활용하여 캐러셀(Carousel) 만들기 (0) | 2022.10.05 |
---|---|
[React] 카드 컴포넌트 검색기능 구현 (1) | 2022.09.29 |
[React] Fragment란? - 단축문법, key가 있는 Fragments (0) | 2022.08.19 |
[React] onKeyUp, onKeyDown, onKeyPress 차이 (0) | 2022.08.17 |
[React] console.log()가 2번 출력되는 이유 (1) | 2022.07.26 |