무한스크롤은 페이지네이션 기법을 응용하여 아래 혹은 위로 스크롤을 할 때, 계속해서 새로운 데이터를 받아오는 방법이다.
무한스크롤을 구현하려면 우선 나타낼 정보를 하나의 박스로 담아야한다. 그리고 그 박스들을 정렬해서 보일 페이지를 꾸민 후, mockup data를 통해 어느정도의 페이지를 구현해본다.
이러한 과정을 거친 후, mockup data가 아닌 실제 api를 받아오고, 이 정보가 박스에 제대로 그려지는지 확인한다.
마지막으로 페이지 혹은 html의 scroll height, scroll top, client height을 가져와 각각의 값을 비교하여 위치에 다다랐을 때 새로운 api를 받아온다.
import axios from "axios";
const apiUrl = "";
const instance = axios.create({
baseURL: apiUrl,
});
export const getComments = async (page, limit) => {
const response = await instance.get(
`/comments?_page=${page}&_limit=${limit}`
);
return response.data;
};
axios library를 통해 GET 요청
axios.create()
함수를 통해 instance를 정의함.instance.get()
파라미터에는 baseURL을 제외한 나머지 부분이 들어갈 수 있다.getComment()
는 try로 감싸져야한다. const [comments, setComments] = useState([]);
const [page, setPage] = useState(1);
const loadComments = async (page) => {
try {
const temp = await getComments(page, 10);
const tempComments = comments.concat(temp);
setComments(tempComments);
} catch (e) {
console.error(e);
}
};
useEffect(() => {
loadComments(page);
}, [page]);
page가 갱신될 때 마다 loadComments가 실행되며, 불러온 data는 temp에 담겨 comments와 이어붙인 후 comments로 초기화된다.
let timeInterver = '';
const scrollEvent = ()=>{
const scrollHeight = document.documentElement.scrollHeight;
const scrollTop = document.documentElement.scrollTop;
const clientHeight = document.documentElement.clientHeight;
console.log(scrollTop)
if (scrollTop + clientHeight >= scrollHeight - 950) {
setPage(page + 1);
}
}
const handleScroll = () => {
clearTimeout(timeInterver);
timeInterver = setTimeout(scrollEvent, 300)
};
useEffect(() => {
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
});
window.addEventListener를 통해 scroll 감지
scrollTop(scroll 상단의 위치) + clientHeight(창의 길이) >= scrollHeight(content 총 길이)
일 때 page를 수정한다.Box 내부의 height
min-height : 63px
으로 3줄 만큼의 크기를 유지시켜 일관성이 유지되도록 했다.처음 infinite scroll을 접했을 때 걱정이 앞섰다. 하지만 pagination을 기존에 구현해봤었고, scroll에 대한 정보를 받아오기만 하면 되는 구조를 파악하니 이해도 쉽고 구현도 어렵지 않았다.
scroll 관련 라이브러리를 활용하여 구현하고 싶었지만 이 부분은 학습이 더 필요할 것 같아서 정보가 많은 쪽으로 택했다. 또한 intersection Observer를 통해 구현하는 부분도 많았는데, 처음엔 이해가 안 되었지만 기본적인 방법으로 구현하고 나니 어떠한 동작으로 진행이 되는지 나중에 깨달았다.
다만 이 방법은 하단에 목표로 하는 target이 어디에 위치해있는지 알아야하기 때문에 스크롤이 하단에 닿기 전에 새로 불러오려고 하는 나의 목적과는 맞지 않는다고 생각한다.