React Router 在 V6 上滚动到顶部
React Router Scroll to Top on V6
当我更改页面时,应用程序保持在与上一页相同的位置。我想在更改页面时从顶部显示组件。为此,我正在尝试实施 React Router ScrollToTop。
我找到了文档并实现了它,但是我使用的是react router v6,所以有点不同。
https://v5.reactrouter.com/web/guides/scroll-restoration
ScrollToTop 组件内的所有内容都没有得到渲染,我最终得到一个空白页面。
App.js:
import { Router, Routes, Route } from "react-router-dom";
import './App.scss';
import Main from './pages/Main';
import Projects from './pages/Projects';
import NavBar from './components/NavBar';
import Footer from './components/Footer';
import ScrollToTop from './components/scrollToTop';
function App() {
return (
<div className="app" id="app">
<NavBar />
<div className='app-body'>
<Router>
<ScrollToTop>
<Routes>
<Route path="/portfolio" element={<Main />} />
<Route path="/portfolio/projects" element={<Projects />} />
</Routes>
</ScrollToTop>
</Router>
</div>
<Footer />
</div>
);
}
export default App;
ScrollToTop.js:
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;
}
您将 Routes
组件作为 ScrollToTop
组件的后代,因此您应该 return children
而不是 null
。
ScrollToTop.js
:
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
export default function ScrollToTop({ children }) {
const { pathname } = useLocation();
useEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);
return children;
}
空白页是因为您正在从 <ScrollToTop>
组件 returning null
。相反,如果您 return <></>
或从 <ScrollToTop >
中获取 {children}
道具和 return,它应该可以工作:)
正如其他人指出的那样,您正在用 ScrollToTop
组件包装 Routes
组件,但我建议将其转换为一个 React 钩子,特别是考虑到它实际上不呈现任何东西,你希望它 运行 作为导航的 side-effect。
function useScrollToTop() {
const { pathname } = useLocation();
useEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);
}
...
function App() {
useScrollToTop();
return (
<div className="App">
<div className="app-body">
<NavBar />
<Routes>
<Route path="/portfolio" element={<Main />} />
<Route path="/portfolio/projects" element={<Projects />} />
</Routes>
</div>
</div>
);
}
这必然需要您在 ReactTree 中将 Router
提升到更高的位置以包装 App
组件,以便它具有用于 useScrollToTop
挂钩的路由上下文。
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<Router>
<App />
</Router>
</StrictMode>,
rootElement
);
当我更改页面时,应用程序保持在与上一页相同的位置。我想在更改页面时从顶部显示组件。为此,我正在尝试实施 React Router ScrollToTop。
我找到了文档并实现了它,但是我使用的是react router v6,所以有点不同。
https://v5.reactrouter.com/web/guides/scroll-restoration
ScrollToTop 组件内的所有内容都没有得到渲染,我最终得到一个空白页面。
App.js:
import { Router, Routes, Route } from "react-router-dom";
import './App.scss';
import Main from './pages/Main';
import Projects from './pages/Projects';
import NavBar from './components/NavBar';
import Footer from './components/Footer';
import ScrollToTop from './components/scrollToTop';
function App() {
return (
<div className="app" id="app">
<NavBar />
<div className='app-body'>
<Router>
<ScrollToTop>
<Routes>
<Route path="/portfolio" element={<Main />} />
<Route path="/portfolio/projects" element={<Projects />} />
</Routes>
</ScrollToTop>
</Router>
</div>
<Footer />
</div>
);
}
export default App;
ScrollToTop.js:
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;
}
您将 Routes
组件作为 ScrollToTop
组件的后代,因此您应该 return children
而不是 null
。
ScrollToTop.js
:
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
export default function ScrollToTop({ children }) {
const { pathname } = useLocation();
useEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);
return children;
}
空白页是因为您正在从 <ScrollToTop>
组件 returning null
。相反,如果您 return <></>
或从 <ScrollToTop >
中获取 {children}
道具和 return,它应该可以工作:)
正如其他人指出的那样,您正在用 ScrollToTop
组件包装 Routes
组件,但我建议将其转换为一个 React 钩子,特别是考虑到它实际上不呈现任何东西,你希望它 运行 作为导航的 side-effect。
function useScrollToTop() {
const { pathname } = useLocation();
useEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);
}
...
function App() {
useScrollToTop();
return (
<div className="App">
<div className="app-body">
<NavBar />
<Routes>
<Route path="/portfolio" element={<Main />} />
<Route path="/portfolio/projects" element={<Projects />} />
</Routes>
</div>
</div>
);
}
这必然需要您在 ReactTree 中将 Router
提升到更高的位置以包装 App
组件,以便它具有用于 useScrollToTop
挂钩的路由上下文。
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<Router>
<App />
</Router>
</StrictMode>,
rootElement
);