React 리액트/React 리액트
react query로 무한스크롤 구현하기
솧디_code
2022. 12. 12. 14:45
import { useQuery, useInfiniteQuery } from "@tanstack/react-query";
import { useInView } from "react-intersection-observer";
import { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useDeleteDetailPost } from "../../querys/detail";
import axios from "axios";
import { Box } from "../../components";
import { Board } from "./board";
const MyBoard = () => {
const BASE_URL = process.env.REACT_APP_SERVER;
const navigate = useNavigate();
//로컬스토리지 토큰가져오기
const authorization = localStorage.getItem("Authorization");
//내가쓴게시물 get요청
const { data, status } = useQuery(
["getMyBoard"],
async () => {
const response = await axios.get(
`${BASE_URL}/member/auth/mypage/boards`,
{
headers: {
authorization,
},
},
);
return response.data;
},
{
if(isError) {
alert("내가 작성한 게시물 불러오기 실패");
},
},
);
위는 기존의 겟 요청이고, 한번에 다불러오는 로직이다. 이렇게되면 한번에 많은 정보들이 다 로딩되기에 좋지않다.
import { useQuery, useInfiniteQuery } from "@tanstack/react-query";
import { useInView } from "react-intersection-observer";
import { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useDeleteDetailPost } from "../../querys/detail";
import axios from "axios";
import { Box } from "../../components";
import { Board } from "./board";
const BASE_URL = process.env.REACT_APP_SERVER;
const authorization = localStorage.getItem("Authorization");
const fetchPostList = async pageParam => {
const { data } = await axios.get(
`${BASE_URL}/member/auth/mypage/boards?page=${pageParam}&size=3`,
{
headers: {
authorization,
},
},
);
const { myPageList: page, isLast } = data;
return { page, nextPage: pageParam + 1, isLast };
};
const MyBoard = () => {
const navigate = useNavigate();
const { ref, inView } = useInView();
const { data, status, fetchNextPage, isFetchingNextPage } = useInfiniteQuery(
["page"],
({ pageParam = 1 }) => fetchPostList(pageParam),
{
getNextPageParam: lastPage =>
!lastPage.isLast ? lastPage.nextPage : undefined,
},
);
console.log("data.pages===>", data?.pages);
useEffect(() => {
if (inView) fetchNextPage();
}, [inView]);
if (status === "loading") return <p>로딩중</p>;
if (status === "error") return <p>에러입니다.</p>;
return (
<Box>
<Board
data={data}
navigate={navigate}
onDeletePost={handelDeletePost}
onEditPost={handleEditPost}
/>
{isFetchingNextPage ? <p>로딩중</p> : <div ref={ref}></div>}
</Box>
);
};
export default MyBoard;
그래서 무한스크롤로 교체하는 작업을 하였고 useInfiniteQuery를 이용해 무한스크롤을 구현하였다.
정보가 끝나는 부분에 ref를 넣어 마지막페이지 여부를 확인하였다.
ui로직을 미리 구분해놓은 컴포넌트 덕분에 간단하게 무한스크롤을 적용할수있었다.
또한 status를 통한 로딩중,에러처리문은 상단에 있을시 오류가 나기에 로직 맨 마지막에 위치하는것이 좋다.