일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 날짜 테스트
- 구름톤챌린지
- 과제 진행하기
- Hermes Engine
- 프로그래머스
- 리액트네이티브
- 통신망분석
- 최솟갑 구하기
- Leetcode #javascript #알고리즘 #Algorithms #js
- jest
- mutationobserver
- nextjs-performance
- 귤 고르기
- 중첩 점
- Google 애널리틱스
- 헤르메스 엔진
- 테이블 해시 함수
- JavaScript
- 연결 요소 제거하기
- create-next-app
- ResizeObserver
- 구름톤
- 자바스크립트
- nextjs
- 구름톤 챌린지
- 테스트 Date
- 호텔 대실
- 리액트네이티브 엔진
- Jest uuid syntax
- mock date
- Today
- Total
나만보는개발공부블로그
Scroll restoration in Nextjs 본문
Nextjs에서의 스크롤 유지 방법
Nextjs에는 페이지 사이를 이동할 때 스크롤 높이를 유지하는 옵션이 있습니다 next/router 의 <Link> 컴포넌트의 요소에 scroll false 옵션을 전달할 수 있고 router.push()에는 scroll false props가 있습니다.
router.push('/url', undefined, { scroll: false });
하지만 위의 옵션들은 스크롤이 window를 참조하는 경우에 작동하지만 특이 케이스에 따라 div 구성 요소를 참조하는 경우에는 작동하지 않을수 있습니다.
이 경우 ref를 임의로 만든 커스텀 스크롤 훅으로 전달해야 합니다.
저같은 경우의 페이지 스크롤은 div를 참조하고 있었고 이 div의 높이는 페이지의 불러오는 사이즈에 따라서 div의 높이가 달라지는 경우였습니다.
처음 렌더링할 때 아이템이 비어 있으므로 그 당시 스크롤 높이는 `window.clientHeight`까지만 확장할 수 있었습니다.
해결방안
저는 react-query를 사용하고 있었고 staleTime 옵션에서 browser의 In-memory에 데이터를 유지하기 위해 useInfiniteQuery를 사용했습니다.
이렇게하면 페이지를 이동하고 다시 페이지로 돌아가더라도 데이터가 캐시되고 항목을 계속 유지하고 스크롤 높이가 이전 높이까지 확장할 수 있엇습니다.
이전 스크롤 높이로 유지하려면 div를 참조하는 ref의 `scrollTop`을 session storage에 저장하고 session storage의 scroll height을 UseEffect() 로직안에 불러온 다음 불러오는 아이템의 변수를 dependency에 추가하였습니다.
이 방법으로 스크롤을 복원할 수 있습니다.
export const SCROLL_HEIGHT_KEY = "SCROLL_HEIGHT";
export const Pagination = () => {
const [scrollViewRef, setScrollViewRef] = useState<HTMLDivElement | null>();
const {
data: allDatas,
fetchNextPage,
} = useInfiniteLibrary(someFilter);
...
const onScroll = useCallback(
(event: any) => {
let element = event.target;
window.sessionStorage.setItem(SCROLL_HEIGHT_KEY, String(element.scrollTop));
if (someConditions) {
fetchNextPage();
}
},
[debouncedSearch, fetchNextPage, myLibrary],
);
...
useEffect(() => {
const scrollHeight = window.sessionStorage.getItem(SCROLL_HEIGHT_KEY);
if (scrollViewRef && scrollHeight) {
scrollViewRef.scrollTo({
top: parseInt(scrollHeight, 10),
behavior: "auto",
});
}
}, [allDatas, scrollViewRef]);
...
return (
<SrollDiv onScroll={onScroll} ref={(ref) => setScrollViewRef(ref)}>
...
</ScrollDiv>
)
}
'Web Development > Front' 카테고리의 다른 글
Nextjs Sentry Performance 설정하기 (0) | 2023.01.09 |
---|---|
Multiple children layout in Nextjs (0) | 2022.09.17 |
[Cypress] window.__coverage__ is undefined (0) | 2022.06.24 |
[NextJS] SEO for SVG image file (0) | 2022.06.07 |
[NextJS] nextjs Error: Plugin name should be specified (0) | 2022.06.07 |