{
//리스트
const [list, setList] = useStateimport styled from "styled-components";
import ResultItem from "./ResultItem";
import fetchData from "../../../api/fetchData";
import useScroll from "../../../hooks/useScroll";
import { useEffect, useState, useCallback } from "react";
import { PayDataListProps } from "./model";
const ResultList = () => {
//리스트
const [list, setList] = useState<PayDataListProps[]>([]);
const [slicedList, setSlicedList] = useState<PayDataListProps[]>([]);
//수치값
const itemHeight = 45;
const nodePadding = 20;
const scrollViewPortHeight = 490;
const [totalContainerHeight, setTotalContainerHeight] = useState<number>(0);
const { scrollTop, scrollContainerRef } = useScroll(
itemHeight,
list,
filteredList
);
//visible 노드 자르기 위한 수치
const startIndex = Math.max(
Math.floor(scrollTop / itemHeight) - nodePadding,
0
);
const visibleNodeCount = Math.floor(
scrollViewPortHeight / itemHeight + 2 * nodePadding
);
const endIndex = startIndex + visibleNodeCount;
const offsetY = startIndex * itemHeight;
//전체 데이터 가져오기
const getMoreData = useCallback(async () => {
try {
const payData = await fetchData();
setList(payData);
setTotalContainerHeight(payData.length * itemHeight);
} catch (e) {
console.error(e);
}
}, []);
useEffect(() => {
getMoreData();
}, []);
//visible nodes 자르기
useEffect(() => {
setSlicedList(list.slice(startIndex, endIndex));
}, [list, startIndex]);
return (
<ResultListBox ref={scrollContainerRef} height={scrollViewPortHeight}>
<TotalItemBox height={totalContainerHeight}>
<VisibleContentsBox offsetY={offsetY}>
{slicedList.length === 0 ? (
<NoResult>
<div>결과가 없어요</div>
<div>검색조건을 확인해주세요</div>
</NoResult>
) : (
slicedList.map((item) => (
<ResultItem key={item.payID} itemHeight={itemHeight} {...item} />
))
)}
</VisibleContentsBox>
</TotalItemBox>
</ResultListBox>
);
};
export default ResultList;
//styled-components
const ResultListBox = styled.div<{ height: number }>`
height: ${(props) => `${props.height}px`};
overflow-y: auto;
padding-right: 1.2rem;
`;
const TotalItemBox = styled.div<{ height: number }>`
height: ${(props) => `${props.height}px`};
position: relative;
`;
const VisibleContentsBox = styled.div<{ offsetY: number }>`
position: absolute;
width: 100%;
transform: translateY(
${(props) => props.offsetY}px
); //px 단위를 안넣어주면 인식이 잘 안됨
`;
const NoResult = styled.div`
text-align: center;
padding: 8rem 0;
font-size: 1.8rem;
font-weight: bold;
> div {
padding: 0.8rem;
}
`;