在React中使用react-router v6.12导航到新路由时滚动到顶部。

huangapple go评论72阅读模式
英文:

Scroll to Top when navigate to a new route in React using react-router v6.12

问题

我在切换到另一个路由时遇到了一个问题,滚动位置保持在前一个路由的相同位置。

我正在使用ReactVite以及react-router v6.12(最新版本)。

我尝试过的方法:我创建了一个处理scrollToTop的组件,并在我的App.jsx中的<Outlet />之前导入和使用它,但似乎它不会滚动到页面顶部(顺便说一句:控制台日志消息已经打印出来)。

当我搜索此问题时,许多人通过以下函数解决了他们的问题,但对我来说不起作用。

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

const ScrollToTop = () => {
    const { pathname } = useLocation();

    useEffect(() => {
        // 第一种方式..不起作用
        window.scrollTo(0, 0);

        // 第二种方式..仍然不起作用
        document.documentElement.scrollTo({
            top: 0,
            left: 0,
            behavior: "instant",
        });

        console.log("Called");
    }, [pathname]);

    return null;
};

export default ScrollToTop;

我的文件结构如下:

main.jsx

import React from "react";
import ReactDOM from "react-dom/client";

import { RouterProvider } from "react-router-dom";
import router from "./router";

import "./App.css";

ReactDOM.createRoot(document.getElementById("root")).render(
    <React.StrictMode>
        <RouterProvider router={router} />
    </React.StrictMode>
);

router.js

import { createBrowserRouter } from "react-router-dom";

import App from "./views/layouts/App.jsx";

import HomePage from "./views/HomePage.jsx";
import Items from "./views/Items.jsx";
import About from "./views/About.jsx";
import Contact from "./views/Contact.jsx";

const router = createBrowserRouter([
    {
        path: "/",
        element: <App />,
        children: [
            {
                path: "/",
                element: <HomePage />,
            },
            {
                path: "/items",
                element: <Items />,
            },
            {
                path: "/about",
                element: <About />,
            },
            {
                path: "/contact",
                element: <Contact />,
            },
        ],
    },
]);

export default router;

App.jsx

import { Outlet } from "react-router-dom";

import ScrollToTop from "../../utilities/ScrollToTop";

import Navbar from "../../components/Navbar";
import Footer from "../../components/Footer";

function App() {
    return (
        <>
            <ScrollToTop />
            <Navbar />
            <div className="content">
                <Outlet />
            </div>
            <Footer />
        </>
    );
}

export default App;

基本上我想要实现以下效果:

  • 当用户导航到新页面(单击<Link>)时,页面必须滚动到顶部位置。
  • 当按下浏览器的返回按钮(而不是点击另一个<Link>返回到上一页时),必须返回到上一页的相同滚动位置(如果可能的话)。

有人能帮助我吗?非常感谢!

英文:

I'm having a problem when I'm going to another route, the scroll position stays on the same position as previous route.

I'm using React with Vite and react-router v6.12 (latest version).

What i've tried: I've created a component that handles the scrollToTop and I have imported and used in my App.jsx before the &lt;Outlet /&gt; but it seems that it doesn't scroll to the top of the page (btw: the console.log message is printed).

When I've searched for this issues, many people solved their issue with below function, but for me it doesn't work.

import { useEffect } from &quot;react&quot;;
import { useLocation } from &quot;react-router-dom&quot;;

const ScrollToTop = () =&gt; {
    const { pathname } = useLocation();

    useEffect(() =&gt; {
        // first way..not working
        window.scrollTo(0, 0);

        // second way..still not working
        document.documentElement.scrollTo({
            top: 0,
            left: 0,
            behavior: &quot;instant&quot;,
        });

        console.log(&quot;Called&quot;);
    }, [pathname]);

    return null;
};

export default ScrollToTop;

My files are structured in this way:

main.jsx

import React from &quot;react&quot;;
import ReactDOM from &quot;react-dom/client&quot;;

import { RouterProvider } from &quot;react-router-dom&quot;;
import router from &quot;./router&quot;;

import &quot;./App.css&quot;;

ReactDOM.createRoot(document.getElementById(&quot;root&quot;)).render(
    &lt;React.StrictMode&gt;
        &lt;RouterProvider router={router} /&gt;
    &lt;/React.StrictMode&gt;
);

router.js

import { createBrowserRouter } from &quot;react-router-dom&quot;;

import App from &quot;./views/layouts/App.jsx&quot;;

import HomePage from &quot;./views/HomePage.jsx&quot;;
import Items from &quot;./views/Items.jsx&quot;;
import About from &quot;./views/About.jsx&quot;;
import Contact from &quot;./views/Contact.jsx&quot;;

const router = createBrowserRouter([
    {
        path: &quot;/&quot;,
        element: &lt;App /&gt;,
        children: [
            {
                path: &quot;/&quot;,
                element: &lt;HomePage /&gt;,
            },
            {
                path: &quot;/items&quot;,
                element: &lt;Items /&gt;,
            },
            {
                path: &quot;/about&quot;,
                element: &lt;About /&gt;,
            },
            {
                path: &quot;/contact&quot;,
                element: &lt;Contact /&gt;,
            },
        ],
    },
]);

export default router;

App.jsx

import { Outlet } from &quot;react-router-dom&quot;;

import ScrollToTop from &quot;../../utilities/ScrollToTop&quot;;

import Navbar from &quot;../../components/Navbar&quot;;
import Footer from &quot;../../components/Footer&quot;;

function App() {
    return (
        &lt;&gt;
            &lt;ScrollToTop /&gt;
            &lt;Navbar /&gt;
            &lt;div className=&quot;content&quot;&gt;
                &lt;Outlet /&gt;
            &lt;/div&gt;
            &lt;Footer /&gt;
        &lt;/&gt;
    );
}

export default App;

Bassically want I want to achive is this:

  • When user navigate to a new page (cliks a < Link >) it must go to that page with scroll position to the top
  • When pressing Back button (from browser Not clicking another < Link > that goes to previous page) must go to the previous page on the same scroll position (if it is possible)

Can someone help me? Thank you in advance!

答案1

得分: 1

以下是代码的中文翻译部分:

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

export default function ScrollToTop() {
    const { pathname } = useLocation();
    useEffect(() => {
        window.scrollTo(0, 0);
    }, [pathname]);

    return null;
}

现在在 App.js 文件中:

function App(){
    <>
    <ScrollToTop />
    <Routes>
    <Route />
    .
    .
    .
    </Routes>
    </>
}

export default App;
英文:

Copy/Paste the code where you export the scrollToTop component file:

import { useEffect } from &quot;react&quot;;
import { useLocation } from &quot;react-router-dom&quot;;

export default function ScrollToTop() {
    const { pathname } = useLocation();
    useEffect(() =&gt; {
        window.scrollTo(0, 0);
    }, [pathname]);

    return null;
}

Now in App.js file

function App(){
&lt;&gt;
&lt;ScrollToTop /&gt;
&lt;Routes&gt;
&lt;Route /&gt;
.
.
.
&lt;/Routes&gt;
&lt;&gt;
}

export default App;

huangapple
  • 本文由 发表于 2023年6月11日 21:29:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76450697.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定