[React] 페이지 이동 시 스크롤 위치 상단으로 고정하기

김채운·2023년 8월 8일
3

React

목록 보기
20/26

이 또한 면접을 가고나서 알게 된 문제였다. 오픈마켓 프로젝트에서 메인페이지에서 상품을 클릭하면 상품 상세 페이지의 스크롤이 아래로 내려가 있는 문제였다. 면접 당시 이 문제점에 대해서 언급하셨고 거기서 제대로 답변하지 못했다. 그래도 덕분에 몰랐던 걸 알게되어서 고칠 수 있다는 거에 감사했다.

이렇게 상세페이지로 이동 시 scroll이 상단에 고정되지 않고 밑으로 내려가있는 문제가 있다.

➡️ 문제 발생

React를 이용하여 페이지 제작 시에 페이지 이동을 Router를 사용하게 되는데, 이때 기본적으로는 스크롤 위치가 이동하지 않는다. 이 말은 내가 메인페이지에서 스크롤을 50 정도로 내려서 보다 그 상태에서 상품의 상세 페이지로 이동하게 되면 메인페이지의 스크롤 상태 그대로 페이지 전환만 된다는 뜻이다.
흔히 웹페이지를 이용해본 사람이라면, 페이지 이동이나 화면 전환이 된 경우 페이지를 맨 위에부터 보기를 원하는데, Router는 스크롤이 해당 위치에 머물게 되는 문제가 있다.

➡️ 문제 발생 원인

1. React Router의 기본 동작과 브라우저의 기본 동작의 충돌

  • React Router를 사용할 때 페이지 이동 시 스크롤 위치가 원하는 대로 최상단으로 이동하지 않는 이유는, React Router의 기본 동작이 브라우저의 기본 동작과 충돌하기 때문이다.
    일반적으로 브라우저에서는 페이지 이동 시에 스크롤 위치를 이전 위치로 유지하지 않고 새로운 페이지의 최상단으로 이동하는 기본 동작이 있다. 이러한 브라우저 기본 동작과 React Router의 동작이 충돌하면서 페이지 이동 시 스크롤 위치가 원하는 대로 조정되지 않는 현상이 발생한다.
    React Router는 React 기반의 라우팅 라이브러리로, 페이지 이동을 처리하고 페이지 간의 상태 관리를 제공한다. 이때 페이지 이동 시에 브라우저의 기본 동작을 막고, React Router가 라우팅을 관리하도록 한다. 그러나 기본적으로는 스크롤 위치를 따로 처리하지 않기 때문에 스크롤 위치가 이동하지 않는 것이다.

2. React의 SPA 특성

  • React는 SPA로 동작하는 특성을 가지고 있다. SPA는 페이지 전환 없이 단일 페이지에서 애플리케이션의 모든 기능을 처리하는 웹 애플리케이션이다. SPA에서는 페이지 이동이 발생해도 실제로는 브라우저가 다른 페이지를 로드하는 것이 아니라, JavaScript를 사용하여 페이지의 일부만 변경하고 데이터를 가져와서 렌더링한다. 이로 인해 사용자가 페이지를 이동할 때 React Router와 같은 라우팅 라이브러리를 사용하여 처리되기 때문에, 페이지 간의 이동이 실제로는 단일 페이지 내에서 컴포넌트의 전환으로 이루어진다. 따라서 스크롤 위치가 변경되지 않고, 사용자가 스크롤을 내린 상태에서 다른 페이지로 이동하더라도 React는 브라우저의 페이지를 로드하지 않으므로 스크롤 위치가 그대로 유지되게 된다.

➡️ 문제 해결 방법

💡 ScrollToTop 컴포넌트 만들기


// ScrollToTop.js

import { useEffect } from "react";
import { useLocation } from "react-router-dom";

export default function ScrollToTop(props) {
    const { pathname } = useLocation();

    useEffect(() => {
        console.log("Scrolling to top");
        window.scrollTo(0, 0);
    }, [pathname]);

    return <>{props.children}</>;
}

이 코드는 React Router의 useLocation 훅을 사용하여 현재 경로(pathname)를 가져온다. 그리고 useEffect훅을 사용하여 pathname이 변경될 때마다 새로운 페이지로 이동할 때 스크롤을 맨 위로 이동시키는 동작을 수행한다. pathname은 페이지 경로를 나타내므로, pathname이 변경된다는 것은 페이지가 변경되는 것을 뜻한다.

그리고 스크롤을 맨 위로 이동시키는 동작은 window.scrollTo를 통해 동작이 수행되는데, 이 메서드는 window.scrollTo(x,y)로 브라우저 창의 스크롤 위치를 지정된 좌표(x,y)로 이동시키는 역할을 한다. x와y는 각각 수평과 수직 방향의 스크롤 위치를 지정하는 값이다.
따라서, window.scrollTo(0, 0) 코드는 x와 y 좌표를 각각 0으로 지정하여 브라우저 창의 스크롤을 맨 위로 이동시키는 역할을 한다.

이렇게 만든 ScrollToTop컴포넌트를 👇

// index.js

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
    <BrowserRouter>
      <ScrollToTop>
        <App />
      </ScrollToTop>
    </BrowserRouter>
  </Provider>
);

이렇게 index.js에 선언해준다. Router 안에 선언해주어야 pathname 을 인식할 수 있기 때문에 꼭 Router 안에 선언해주도록 한다.

그럼 아까와는 다르게 페이지 이동이 이루어져도 스크롤이 상단에 위치하는 걸 확인할 수 있다.

1개의 댓글

comment-user-thumbnail
2023년 8월 8일

글 잘 봤습니다.

답글 달기