React url변경시(페이지이동시) 화면 상단으로 띄우기 (feat : Scroll Restoration)

bebrain·2023년 9월 21일
1

다른 페이지로 이동하여 url이 바뀌었는데도 화면 최상단으로 이동하지 않고 이전페이지의 스크롤위치 그대로 렌더링되는 현상 발견.

브라우저 기본설정상 따로 코드를 넣지 않아도 당연히 url이 바뀌면 화면 상단으로 이동해야할텐데 잘못 알고 있었나? 싶어서 찾아보았다.

원인

React의 기본적인 구조로 인한 문제였다. React-router를 사용하여 페이지를 이동하게 되는데 새로고침되는 것처럼 보이지만 실상은 페이지 전환 없이 단일 페이지 내에서 컴포넌트만 갈아끼워지는 SPA구조라는 사실을 잊고 있었다.
페이지가 아닌 컴포넌트의 전환만 일어나기 때문에 브라우저 입장에서 이 페이지는 새 페이지가 아닌 기존 페이지에서 데이터만 부분적으로 바뀌었다고 판단하기 때문에 스크롤위치 또한 기존 그대로 유지되는 것이다.

해결방법

scrollToTop이라는 함수를 만들어 주고 useLocation훅을 통해 pathname을 가져온 다음, 이 router경로가 바뀐 것을 감지할 때마다 페이지 최상단으로 이동하도록 index.tsx에 설정해주었다.

// scrollToTop.tsx

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

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

    useEffect(() => {
        window.scrollTo(0, 0);
    }, [pathname]);

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

import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import App from "./App";
import "./style/index.css";
import { ThemeProvider } from "styled-components";
import { theme } from "./style/theme";
import ScrollToTop from "@components/common/ScrollToTop";

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
    <React.StrictMode>
        <ThemeProvider theme={theme}>
            <BrowserRouter>
                <ScrollToTop>
                    <Routes>
                        <Route path="/*" element={<App />} />
                    </Routes>
                </ScrollToTop>
            </BrowserRouter>
        </ThemeProvider>
    </React.StrictMode>
);

참조
참조2

0개의 댓글