我正在使用react-router-dom开发一个React应用程序。我希望每次路线更改时页面都滚动到顶部。这是我尝试过的:
使用带有 useEffect 的自定义钩子:
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
const useScrollToTop = () => {
const { pathname } = useLocation();
useEffect(() => {
console.log("Attempting to scroll to top"); // Logs correctly
window.scrollTo({
top: 0,
behavior: "auto",
});
console.log("Scroll executed"); // Also logs correctly
}, [pathname]);
};
export default useScrollToTop;
在我的 App.tsx 中添加了钩子:
import useScrollToTop from './hooks/useScrollToTop';
const App = () => {
useScrollToTop();
return (
<BrowserRouter>
<Routes>
{/* My routes */}
</Routes>
</BrowserRouter>
);
};
验证window.scrollTo执行(出现日志),但页面没有滚动到顶部。
我还测试过:
a. useLayoutEffect 而不是 useEffect。
b.使用 setTimeout 强制延迟。
c.检查可滚动元素(html、body 或自定义容器)。
d. CSS 修复,例如确保 html, body { height: auto;溢出:可见; }。
e.尽管如此,页面仍然没有滚动到顶部。有什么我遗漏的东西或者我应该检查的干扰吗?
您的自定义挂钩显然位于路由器之外:
const App = () => {
useScrollToTop();
return (
<BrowserRouter>
<Routes>
{/* My routes */}
</Routes>
</BrowserRouter>
);
};
因此它不可能访问
BrowserRouter
提供给 useLocation
钩子和所有其他 RRD 钩子和组件的路由上下文。
将
useScrollToTop
钩子移至路由器内呈现的组件,以便它可以正确访问路由上下文。
示例:
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
const ScrollToTop = () => {
const { pathname } = useLocation();
useEffect(() => {
window.scrollTo({
top: 0,
behavior: "auto",
});
}, [pathname]);
return null;
};
export default useScrollToTop;
const App = () => {
return (
<BrowserRouter>
<ScrollToTop />
<Routes>
{/* My routes */}
</Routes>
</BrowserRouter>
);
};