๐ค ์์งlog ๐ค
[REACT] Infinite scroll (๋ฌดํ์คํฌ๋กค) ๊ตฌํํ๊ธฐ ๋ณธ๋ฌธ
๊ธฐ์กด์ NodeJS๋ก ๋ง๋ค์ด๋ ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ get ํด์์ ํ๋ก ํธ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์ง์ ๋ฌดํ์คํฌ๋กค์ ๊ตฌํํด๋ณด์๋ค.
์์ ์ ํด๋ดค๋๊ฑด๋ฐ ๋ค์ ํ๋ ค๋ ํท๊ฐ๋ฆฌ๊ธฐ ์์ ...๐ต๐ซ ; ๊ทธ๋๋ ์ด์ฐ์ด์ฐ ๊ตฌํ์ ํด๋ณด์๋ค ..
์คํฌ๋กค์ด ์์ง์ด๋ฉด ๋ฐ์ดํฐ๋ฅผ ๊ณ์ ํด์ ๋ถ๋ฌ์จ๋ค.
( + ์คํฌ๋กค์ด ๋ฐ๋ฅ์ ๋ฟ์ผ๋ฉด ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๋ ์ฝ๋๋ ๊ตฌํ์์ )
// useGetFruits.ts
import axios from "axios";
import { useInfiniteQuery } from "react-query";
const fetchFruits = async () => {
const { data } = await axios.get(`http://localhost:8080/fruits`);
return data;
};
const useGetFruits = () => {
return useInfiniteQuery("fruits", fetchFruits, {
getNextPageParam: (lastPage, allPages) => {
if (lastPage.length > 0) return undefined;
return allPages.length + 1;
},
});
};
export default useGetFruits;
// Main.tsx
import { useCallback, useEffect, useRef, useState } from "react";
import styled from "styled-components";
import useGetFruits from "src/api/useGetFruits";
import Fruit from "src/templates/Fruit";
import { FruitType } from "src/types/Fruit";
const Main = () => {
const { data, fetchNextPage, hasNextPage, isFetchingNextPage } =
useGetFruits();
const [loadData, setLoadData] = useState(false);
const ref = useRef<any>(null);
const handleScroll = useCallback(() => {
const { clientHeight, scrollTop, scrollHeight } = ref.current;
if (
clientHeight + scrollTop >= scrollHeight - 1 &&
hasNextPage &&
!isFetchingNextPage
) {
setLoadData(true);
}
}, [hasNextPage, isFetchingNextPage]);
useEffect(() => {
if (loadData) {
fetchNextPage();
setLoadData(false);
}
}, [loadData, fetchNextPage]);
useEffect(() => {
if (ref.current) {
window.addEventListener("scroll", handleScroll, true);
}
return () => {
if (ref.current) {
window.removeEventListener("scroll", handleScroll, true);
}
};
}, [handleScroll]);
return (
<Container>
<Title>๐ Infinite_Scroll ๐</Title>
<List ref={ref}>
{data &&
data.pages.map((pageData) =>
Array.isArray(pageData)
? pageData.map((fruit: FruitType) => (
<Fruit key={fruit.id} fruit={fruit} />
))
: null
)}
</List>
</Container>
);
};
const Container = styled.div`
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
text-align: center;
`;
const Title = styled.h2`
font-size: 50px;
`;
const List = styled.div`
margin: 20px 0 0;
font-size: 35px;
`;
export default Main;
728x90
'๐ React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[REACT] react-daum-postcode๋ฅผ ์ด์ฉํ์ฌ ์ฐํธ๋ฒํธ ๊ฒ์ ๊ตฌํํ๊ธฐ (1) | 2023.10.30 |
---|---|
[REACT] React-webcam ๊ตฌํํ๊ธฐ (0) | 2023.10.19 |
[REACT] QueryClient , Query Invalidation (0) | 2023.09.25 |
[REACT] NodeJS ๋ก ๋ง๋ API๋ฅผ ์ด์ฉํด CRUD ๊ตฌํํ๊ธฐ (0) | 2023.09.22 |
[REACT] ReactQuery (0) | 2023.08.24 |