페이지네이션 포스팅 한 김에 성격이 비슷한 무한스크롤도 정리를 해본다!
무한스크롤은 굉장히 어려울 것 같았는데, pagination을 하고나니 의외로 쉬웠다. 둘의 차이점은 setState에 있다.
pagination은 불러온 데이터를 그대로 setState()에 넣어 변경하지만 infinite scroll은 처음에만 그대로 넣고, 그 후에는 전개연산자(spread operator)를 이용해서 기존의 state에 더해서 변경하는 방식이다.
이를 구현하는데에는 post로 정보를 요청할 때 단 한개의 boolean 속성만 추가하면 된다.
scroll event는 당연히 구현하는데, react에서 event listener를 추가하는건 처음이라 조금 헤맸는데, pure js에서 한 것과 똑같았다.
먼저 이번에도 infinite를 구현하는 infinite.jsx와 그를 불러오는 infiniteLanding.jsx로 나뉜다.
infinite.jsx
import React, {useEffect, useState} from 'react'
import Card from '../utils/card/card';
const Infinite = ({posts, fetching, fetchMoreData}) => {
const [postInfo, setPostInfo] = useState([]);
useEffect(() => {
setPostInfo(posts);
}, [posts])
const handleScroll = () => {
const scrollHeight = document.documentElement.scrollHeight;
const scrollTop = document.documentElement.scrollTop;
const clientHeight = document.documentElement.clientHeight;
if(scrollTop + clientHeight >= scrollHeight && fetching === false) {
fetchMoreData();
}
}
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => {window.removeEventListener('scroll', handleScroll)
}
})
return (
<div>
{ postInfo && postInfo.map((post, idx) => (
<Card key={idx} listInfo={post} />
))}
</div>
)
}
export default Infinite
설명을 길게 해야하는데 밥이 배달와버렸다. 일단 코드를 모두 올리고 다음에 다시 부연설명 해야겠다.
일단 여기서 중요한 점은 postInfo의 값이 들어와있는 상태를 체크하기 위해 postInfo &&를 먼저 조건으로 주었다는 것이고,
useEffect에서 scroll event를 더하는 것이다.
infiniteLanding.jsx
import React, {useState, useEffect} from 'react'
import axios from 'axios'
import Infinite from './sections/infinite'
const InfiniteLanding= () => {
const [listInfo, setListInfo] = useState([]);
const [skip, setSkip] = useState(0);
const [limit, setLimit] = useState(10);
const [fetching, setFetching] = useState(false);
useEffect(() => {
const body = {
skip: skip,
limit: limit,
};
getData(body)
}, [])
const getData = (body) => {
axios.post("/api/url", body)
.then( res => {
if(body.loadMore) setListInfo([...listInfo, ...res.data.listInfo]);
else setListInfo(res.data.listInfo)
})
.catch(err => alert("글을 가져오는데 실패 했습니다.");)
}
const fetchMoreData = () => {
setFetching(true);
let tmpSkip = skip + limit
let body = {
skip: tmpSkip,
limit: limit,
filters: filters,
loadMore: true
};
getData(body);
setSkip(tmpSkip);
setFetching(false);
}
return (
<div>
<h2>TITLE</h2>
<div>
<Infinite posts={listInfo} fetchMoreData={fetchMoreData} fetching={fetching}/>
</div>
)
}
export default InfiniteLanding
아 오늘 하필 국수라서 빨리 안먹으면 금방 불것 같다..
다음에 꼭 이어서 정리해야겠다
일다 이렇게 하며 구현도ㅣㄴ다!
6 thoughts to “React – Infinite Scroll, 무한 스크롤 구현하기”
국수는 못참죠! 글 감사합니다 ㅎ
방문해주셔서감사합니다~
보고 따라할려고했는데 어렵네요 함수형으로 작성할까햇는데… api따는거 분리하고.
다급함이 느껴지는 마지막줄ㅋㅋㅋ 감사합니다!
감사합니다! 많은 도움 됐습니다!!
감사합니다 많은 도움 됐습니다! 🙂