안녕하세요
오늘은 최근 겪었던 Scroll 복원이 되지 않은 이슈 경험을 소개드리겠습니다.
저희 사이트가 모바일화 전환되면서 기존에 데이터 리스트 pagination이 사라지고 InfinityScroll 전부 바꾸었습니다.
1,2,3,4... 페이징이 있었는데 사라졌다
InfinityScroll로 바꾸게 되면서 스크롤 복원 이슈가 생겼다.
예를 들면 초기 데이터 랜더링을 40개를 UI로 뿌려주고 InfinityScroll로 인해 40개씩 더 받아오는 상황에서
리스트를 클릭 -> 상세페이지로 넘어갔다가 뒤로가기시 스크롤이 복원이 되지 않는다.
이유는 router.push router.back 하는 과정에서 InfinityScroll의 상태는 다시 초기 상태로 돌아가기 때문이다.
일단 InfinityScroll상태부터 유지하도록 하자
일단 InfinityScroll의 상태를 유지를 해야 router.push를 하든 back을 하든 스크롤 복원이 정상적으로 가능할 것이다.
간단히 기존 zustand로 상태 관리하고 있던 page상태를 삭제하고 InfinityScroll 발생시
해당 코드를 통해 url query로 page 상태를 관리 할것이다
const { page } = router.query;
router.replace(
{
pathname: router.pathname,
query: { ...router.query, page: Number(page) + 1 },
},
undefined,
{ scroll: false,shallow:true },
);
사이트 결과 url 주소
이제 스크롤 복원 잘 되겠지?
InfinityScroll url query 상태에 따라 리스트가 잘 나오는 것을 확인 했고 이제 스크롤 복원이 잘 되겠지?!라는 기대감으로
시도를 해보았다. 하지만... 왜 인지 자꾸 이상한 지점에서 스크롤이 걸치는 상황만 발생하였다.
원인
리스트 데이터를 받아오기전 기본 40개가 나오는 스켈레톤 로딩을 사용한다.
하지만 page=3이지만 스켈레톤 갯수가 40개가 존재하기 때문에 스크롤이 40개 마지막 요소로 복원이 된다.
40*3 = 120개 라는 조건을 충족하지 못하고 스크롤 복원을 실행하기 때문이다.
해결
주먹구구식 해결 방법이지만 page값에 맞춰 스켈레톤 갯수를 늘려주면 된다. page * 40
{isValidating ? (
<SkeletonLoading length={Number(page) * 40} />
) : (
<div style={{ width: '100%' }}>
{list?.items?.length === 0 && <NoListDataBox />}
<GridContainer list={list?.items ?? []} category={selectedCategory?.displayName} contents_category={'1'} />
</div>
)}
const SkeletonLoading = ({ length = 40 }) => {
return (
<Container>
{Array.from({ length: length }).map((_, index) => (
<CardContainer key={index}>
<ImgContainer>
<div />
</ImgContainer>
<Category />
<Title />
</CardContainer>
))}
</Container>
);
};
'개발' 카테고리의 다른 글
[복붙, velog 2023-03-09] 아이웨딩 Yarn workspace 모노레포 프로젝트 (0) | 2024.05.24 |
---|---|
[velog 2022-10-07] NodeJS 서버와 Docker 폴더 마운트 (VOLUME) (1) | 2024.05.23 |
[velog 2022-06-28] NextJS _middleware 사용하기 (0) | 2024.05.23 |
[velog 2022-06-27] NodeJS 레디스(Redis) 사용하기 (0) | 2024.05.23 |
[velog 2022-06-21] NextJS 서버사이드 301 리다이렉트(redirect) (0) | 2024.05.23 |