: 파이널 프로젝트를 하면서 무한 스크롤 기능이 필요하게 되어 직접 구현해봤다. 처음에 뭔가 어려울거 같았지만, 막상 해보니 별거 없었다.
내가 구현한 기능은 스크롤을 웹 화면에서 가장 밑에서 스크롤을 더 내리면, 새로운 데이터들을 가지고 와서 화면에 렌더하는 기능이다.
무한 스크롤 기능의 원리는 간단하지만, 그전에 알아야할 것이 있다.
window.innerHeight : 크롬을 기준으로 클라이언트에서 보여지는 화면중, 탭창, url주소창, 북마크탭을 제외한 브라우저의 높이.(innerHeight와 반대되는것은 outerHeight다.)
window.scrollY : 현재 나의 스크롤바의 위치.
document.body.offsetHeight : 앞에 body가 붙어 있으므로 이것은 바디의 높이를 말한다.
import React, { useState } from 'react';
import { useSelector } from 'react-redux';
import { RootState } from '../../reducers';
import MainDrinkList from '../organisms/MainDrinkList';
import MainSelectSection from
import axios from 'axios';
interface Props {
id: number;
drinkName: string;
drinkImage: string;
alcohol: number;
};
const Main = (): JSX.Element => { // Main Component
const state = useSelector((state: RootState) => state.personalTypeReducer);
const [drinkList, setDrinkList] = useState<Props[]>([]);
let submitHandler = async () => {
let submitTaste = await axios.post('http://localhost:8080/drinks/list/type', {
...state.types
})
let { data } = submitTaste;
setDrinkList(data)
}
let selectAllHandler = async () => {
let submitAll = await axios.get('http://localhost:8080/drinks/list')
let { data } = submitAll;
setDrinkList(data);
}
window.onscroll = async (e :any) => {
// 본격적인 스크롤링 기능( 여기서 부터 참고 !)
try {
if((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
//window.innerHeight(브라우저 위의 탭+북마크+주소창을 제외한 브라우저 height) + window scrollY(현재 스크롤바의 위치)한 값이 document height(전체 웹 height)보다 클 경우,
let infinityScroll = await axios.get(`http://localhost:8080/drinks/list/${drinkList.length}`);
let { data } = infinityScroll;
setDrinkList(drinkList.concat(data))
}
} catch (err) {
console.log(err)
}
}
return (
<div>
<MainSelectSection submitHandler={submitHandler} selectAllHandler={selectAllHandler} />
<MainDrinkList drinkList={drinkList} />
</div>
)
}
위에 적었던 알아야할 3가지를 참고하여,
window.innerHeight + window.scrollY 의 값이 document.body.offsetHeight)보다 크면 axios 요청을 보내도록 하였다. 정말 생각보다 너무 간단하다....