작성
·
2.5K
1
infinite scroll을 하다가 게시글을 누르면 해당 게시글로 이동하고, 뒤로가기를 누르면 원래 보던 scroll 위치로 이동하도록 만들고 싶습니다.
마치 인스타그램 게시글들을 보다가 프로필을 누르면 프로필 페이지로 이동하고 뒤로가기를 누르면 원래 보던 위치로 돌아가는 것처럼 구현하고 싶습니다.
시도한 방법
scroll 위치는 localStorage를 이용해서 저장했습니다. 문제는 게시글들인데 게시물들은 아래와 같이 ssr을 이용해서 미리 불러왔습니다.
export const getServerSideProps = wrapper.getServerSideProps(
(store) =>
async ({ req, query, resolvedUrl, res }) => {
// login
const cookie = req.headers?.cookie;
axios.defaults.headers.Cookie = "";
if (cookie) {
axios.defaults.headers.Cookie = cookie;
}
store.dispatch({
type: CHECK_LOGIN_REQUEST,
});
// board
if (
store.getState().board.previousUrl === null ||
store.getState().board.previousUrlType !== query.type
) {
store.dispatch({
type: SAVE_PREVIOUS_URL_TYPE,
data: query.type,
});
store.dispatch({
type: SAVED_POSTS_INITIALIZE,
});
store.dispatch({
type: LOAD_BOARD_REQUEST,
data: { type: resolvedUrl },
});
}
store.dispatch(END);
await store.sagaTask.toPromise();
}
);
게시글 페이지로 이동하면 지금까지 본 게시글들이 사라지고, 다시 돌아오면 load되면서 scrollHeight가 localStorage에 저장된 scroll 위치보다 작아지면서 이동하지 않는 현상이 발생합니다.
어떻게 하면 되는지 조언 부탁드립니다.
답변 4
0
useEffect(() => {
window.scrollTo(0, 300);
}, []);
const scrollPos = () => {
console.log(window.scrollY);
localStorage.setItem("y", window.scrollY);
};
useEffect(() => {
window.addEventListener("scroll", scrollPos);
return () => window.removeEventListener("scroll", scrollPos);
}, []);
구글링해도 원하는 대답이 안 나와서 질문드립니다.
scrollTo를 300으로 설정했는데 321은 왜 나오는 건가요?
useEffect(() => {
window.scrollTo(0, 300);
}, []);
const scrollPos = () => {
// console.log(window.scrollY);
localStorage.setItem("y", window.scrollY);
};
useEffect(() => {
console.log(window.scrollY);
window.addEventListener("scroll", scrollPos);
return () => window.removeEventListener("scroll", scrollPos);
}, []);
또 위와 같이 작성하면 window.scrollY가 300으로 출력됩니다. 어디서 제가 놓친걸까요?
0
저기처럼 디바운싱으로 위치를 저장하시고 리로딩 시에만 스크롤 복원을 하시면 될 것 같습니다. setTimeout을 300 정도 주고난 다음에 window.scrollTo 해보세요.
0
조언해주신 방법대로 useSWRInfinite 이용해서 scrollHeight 문제 해결했습니다. 감사합니다.
또 궁금한 점들이 있습니다.
useEffect(() => {
const y = localStorage.getItem("y");
if (y) window.scrollTo(0, y);
}, []);
const scrollPos = useDebouncedCallback(() => {
localStorage.setItem("y", window.scrollY);
}, 100);
useEffect(() => {
window.addEventListener("scroll", scrollPos);
return () => window.removeEventListener("scroll", scrollPos);
}, []);
1.
위와 같이 작성하여 previous scroll position을 저장하도록 구현했습니다.
scroll event가 너무 자주 발생해서 debounce를 이용해서 일정 시간 동안은 동작하지 않도록 만들었습니다.
혹시 위 방법 말고 다른 방법으로 previous scroll position을 저장할 수 있는 방법이 있을까요?
2.
reload한 뒤에도 previous scroll position이 적용되도록 만들 수 있나요?
시도한 방법 1
useEffect(() => {
const y = localStorage.getItem("y");
if (y) {
window.scrollTo(0, y);
}
window.onbeforeunload = () => {
localStorage.setItem("y", window.scrollY);
};
}, []);
beforeunload 이벤트로 scroll position은 저장이 되는데 해당 위치로 scroll이 이동하진 않습니다.
시도한 방법 2
useEffect(() => {
const y = localStorage.getItem("y");
if (y) {
window.scrollTo(0, y);
}
return () => localStorage.setItem("y", window.scrollY);
}, []);
clean up effect를 사용해봤지만 이렇게 하면 window.scrollY가 0이 됩니다.
조언 부탁드립니다.
그럼 유저가 다른 페이지에 갔다가 돌아오면 이전까지 본 모든 게시글들을 swr을 통해 가져오는 건가요?