adr*_*nto 64 javascript reactjs react-router react-router-redux
导航到另一个页面时出现问题,其位置将保持与之前的页面相同.所以它不会自动滚动到顶部.我也试过window.scrollTo(0, 0)在onChange路由器上使用.我也使用scrollBehavior来解决这个问题,但它没有用.对此有何建议?
mtl*_*mtl 81
React Router v4的文档包含用于滚动恢复的代码示例.这是他们的第一个代码示例,当页面导航到以下时,它作为"滚动到顶部"的站点范围解决方案:
class ScrollToTop extends Component {
componentDidUpdate(prevProps) {
if (this.props.location !== prevProps.location) {
window.scrollTo(0, 0)
}
}
render() {
return this.props.children
}
}
export default withRouter(ScrollToTop)
Run Code Online (Sandbox Code Playgroud)
然后将其呈现在应用程序的顶部,但在路由器下方:
const App = () => (
<Router>
<ScrollToTop>
<App/>
</ScrollToTop>
</Router>
)
// or just render it bare anywhere you want, but just one :)
<ScrollToTop/>
Run Code Online (Sandbox Code Playgroud)
显然这适用于大多数情况,但更多关于如何处理选项卡式接口以及为什么没有实现通用解决方案.
Sae*_*ani 52
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;
}
Run Code Online (Sandbox Code Playgroud)
然后在你的应用程序顶部渲染它,但在路由器
下面是在 app.js 中
import ScrollToTop from "./scrollToTop";
function App() {
return (
<Router>
<ScrollToTop />
<App />
</Router>
);
}
Run Code Online (Sandbox Code Playgroud)
或者在 index.js 中
import ScrollToTop from "./scrollToTop";
ReactDOM.render(
<BrowserRouter>
<ScrollToTop />
<App />
</BrowserRouter>
document.getElementById("root")
);
Run Code Online (Sandbox Code Playgroud)
zur*_*fyx 32
但上课是如此2018
ScrollToTop.js
import { useEffect } from 'react';
import { withRouter } from 'react-router-dom';
function ScrollToTop({ history }) {
useEffect(() => {
const unlisten = history.listen(() => {
window.scrollTo(0, 0);
});
return () => {
unlisten();
}
}, []);
return (null);
}
export default withRouter(ScrollToTop);
Run Code Online (Sandbox Code Playgroud)
用法:
<Router>
<Fragment>
<ScrollToTop />
<Switch>
<Route path="/" exact component={Home} />
</Switch>
</Fragment>
</Router>
Run Code Online (Sandbox Code Playgroud)
ScrollToTop也可以实现为包装器组件:
ScrollToTop.js
import React, { useEffect, Fragment } from 'react';
import { withRouter } from 'react-router-dom';
function ScrollToTop({ history, children }) {
useEffect(() => {
const unlisten = history.listen(() => {
window.scrollTo(0, 0);
});
return () => {
unlisten();
}
}, []);
return <Fragment>{children}</Fragment>;
}
export default withRouter(ScrollToTop);
Run Code Online (Sandbox Code Playgroud)
用法:
<Router>
<ScrollToTop>
<Switch>
<Route path="/" exact component={Home} />
</Switch>
</ScrollToTop>
</Router>
Run Code Online (Sandbox Code Playgroud)
Gab*_*e M 32
您可以添加到 Route 组件的 React Hook。使用useLayoutEffect而不是自定义侦听器。
import React, { useLayoutEffect } from 'react';
import { Switch, Route, useLocation } from 'react-router-dom';
export default function Routes() {
const location = useLocation();
// Scroll to top if path changes
useLayoutEffect(() => {
window.scrollTo(0, 0);
}, [location.pathname]);
return (
<Switch>
<Route exact path="/">
</Route>
</Switch>
);
}
Run Code Online (Sandbox Code Playgroud)
更新:更新为使用useLayoutEffect而不是useEffect,以减少视觉卡顿。这大致翻译为:
useEffect: 渲染组件 -> 绘制到屏幕 -> 滚动到顶部(运行效果)useLayoutEffect: 渲染组件 -> 滚动到顶部(运行效果) -> 绘制到屏幕根据您是否正在加载数据(想想微调器)或者您是否有页面过渡动画,useEffect可能更适合您。
Luk*_*kas 28
这个答案是遗留代码,路由器v4 +检查其他答案
<Router onUpdate={() => window.scrollTo(0, 0)} history={createBrowserHistory()}>
...
</Router>
Run Code Online (Sandbox Code Playgroud)
如果它不起作用,你应该找到原因.在里面componentDidMount
document.body.scrollTop = 0;
// or
window.scrollTo(0,0);
Run Code Online (Sandbox Code Playgroud)
你可以使用:
componentDidUpdate() {
window.scrollTo(0,0);
}
Run Code Online (Sandbox Code Playgroud)
你可以添加一些标志,如"scrolled = false",然后在更新中:
componentDidUpdate() {
if(this.scrolled === false){
window.scrollTo(0,0);
scrolled = true;
}
}
Run Code Online (Sandbox Code Playgroud)
Dra*_*scu 25
对于react-router v4,这是一个实现滚动恢复的create-react-app:http://router-scroll-top.surge.sh/.
为此,您可以创建装饰Route组件并利用生命周期方法:
import React, { Component } from 'react';
import { Route, withRouter } from 'react-router-dom';
class ScrollToTopRoute extends Component {
componentDidUpdate(prevProps) {
if (this.props.path === this.props.location.pathname && this.props.location.pathname !== prevProps.location.pathname) {
window.scrollTo(0, 0)
}
}
render() {
const { component: Component, ...rest } = this.props;
return <Route {...rest} render={props => (<Component {...props} />)} />;
}
}
export default withRouter(ScrollToTopRoute);
Run Code Online (Sandbox Code Playgroud)
在componentDidUpdate我们可以检查位置路径名何时更改并将其与path道具匹配,如果满足,则恢复窗口滚动.
这种方法有什么好处,我们可以拥有恢复滚动的路由和不恢复滚动的路由.
以下是App.js如何使用上述内容的示例:
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
import Lorem from 'react-lorem-component';
import ScrollToTopRoute from './ScrollToTopRoute';
import './App.css';
const Home = () => (
<div className="App-page">
<h2>Home</h2>
<Lorem count={12} seed={12} />
</div>
);
const About = () => (
<div className="App-page">
<h2>About</h2>
<Lorem count={30} seed={4} />
</div>
);
const AnotherPage = () => (
<div className="App-page">
<h2>This is just Another Page</h2>
<Lorem count={12} seed={45} />
</div>
);
class App extends Component {
render() {
return (
<Router>
<div className="App">
<div className="App-header">
<ul className="App-nav">
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/another-page">Another Page</Link></li>
</ul>
</div>
<Route exact path="/" component={Home} />
<ScrollToTopRoute path="/about" component={About} />
<ScrollToTopRoute path="/another-page" component={AnotherPage} />
</div>
</Router>
);
}
}
export default App;
Run Code Online (Sandbox Code Playgroud)
从上面的代码中,有趣的是,只有在导航到/about或/another-page滚动到顶部动作时才会执行.但是,当进行时,/不会发生滚动恢复.
整个代码库可以在这里找到:https://github.com/rizedr/react-router-scroll-top
Has*_*zad 16
对于“REACT-ROUTER-DOM v6 及更高版本”
我通过创建一个包装函数并将其包装在所有路由周围解决了以下问题。
请按照以下步骤操作:
1:您需要导入以下内容:
import {Routes, Route, BrowserRouter as Router, useLocation} from 'react-router-dom';
import {useLayoutEffect} from 'react';
Run Code Online (Sandbox Code Playgroud)
2:在“App”函数上方编写一个包装函数:
const Wrapper = ({children}) => {
const location = useLocation();
useLayoutEffect(() => {
document.documentElement.scrollTo(0, 0);
}, [location.pathname]);
return children
}
Run Code Online (Sandbox Code Playgroud)
3:现在将您的路由包装在包装函数中:
<BrowserRouter>
<Wrapper>
<Navbar />
<Routes>
<Route exact path="/" element={<Home/>} />
<Route path="/Products" element={<Products/>} />
<Route path="/Login" element={<Login/>} />
<Route path="/Aggressive" element={<Aggressive/>} />
<Route path="/Attendance" element={<Attendance/>} />
<Route path="/Choking" element={<Choking/>} />
<Route path="/EmptyCounter" element={<EmptyCounter/>} />
<Route path="/FaceMask" element={<FaceMask/>} />
<Route path="/Fainting" element={<Fainting/>} />
<Route path="/Smoking" element={<Smoking/>} />
<Route path="/SocialDistancing" element={<SocialDistancing/>} />
<Route path="/Weapon" element={<Weapon/>} />
</Routes>
<Footer />
</Wrapper>
</BrowserRouter>
Run Code Online (Sandbox Code Playgroud)
这应该可以解决问题。
leh*_*ang 15
值得注意的是该onUpdate={() => window.scrollTo(0, 0)}方法已经过时了。
这是适用于react-router 4+的简单解决方案。
const history = createBrowserHistory()
history.listen(_ => {
window.scrollTo(0, 0)
})
<Router history={history}>
Run Code Online (Sandbox Code Playgroud)
Kep*_*pro 11
React 钩子 2020 :)
import React, { useLayoutEffect } from 'react';
import { useLocation } from 'react-router-dom';
const ScrollToTop: React.FC = () => {
const { pathname } = useLocation();
useLayoutEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);
return null;
};
export default ScrollToTop;
Run Code Online (Sandbox Code Playgroud)
在下面的组件中 <Router>
只需添加一个 React Hook(以防您不使用 React 类)
React.useEffect(() => {
window.scrollTo(0, 0);
}, [props.location]);
Run Code Online (Sandbox Code Playgroud)
小智 9
2021 年 8 月
您可以在 App.js 中执行此操作,而不是在每个页面中执行此操作
import { useLocation } from "react-router-dom";
const location = useLocation();
useEffect(() => {
window.scrollTo(0,0);
}, [location]);
Run Code Online (Sandbox Code Playgroud)
设置位置useEffect将确保每次路径更改时滚动到顶部。
我的应用程序遇到了同样的问题.使用下面的代码片段帮助我在点击下一个按钮时滚动到页面顶部.
<Router onUpdate={() => window.scrollTo(0, 0)} history= {browserHistory}>
...
</Router>
Run Code Online (Sandbox Code Playgroud)
但是,问题仍然存在于浏览器上.经过大量的试验,意识到这是因为浏览器窗口的历史对象,它有一个属性scrollRestoration,设置为auto.Setting这个手动解决了我的问题.
function scrollToTop() {
window.scrollTo(0, 0)
if ('scrollRestoration' in history) {
history.scrollRestoration = 'manual';
}
}
<Router onUpdate= {scrollToTop} history={browserHistory}>
....
</Router>
Run Code Online (Sandbox Code Playgroud)
钩子是可组合的,从 React Router v5.1 开始,我们有了一个useHistory()钩子。因此,基于@zurfyx 的回答,我为此功能创建了一个可重复使用的钩子:
// useScrollTop.ts
import { useHistory } from 'react-router-dom';
import { useEffect } from 'react';
/*
* Registers a history listener on mount which
* scrolls to the top of the page on route change
*/
export const useScrollTop = () => {
const history = useHistory();
useEffect(() => {
const unlisten = history.listen(() => {
window.scrollTo(0, 0);
});
return unlisten;
}, [history]);
};
Run Code Online (Sandbox Code Playgroud)
2021 (React 16) - 基于@Atombit 的评论
下面滚动到顶部,但也保留历史滚动位置。
function ScrollToTop() {
const history = useHistory()
useEffect(() => {
const unlisten = history.listen((location, action) => {
if (action !== 'POP') {
window.scrollTo(0, 0)
}
})
return () => unlisten()
}, [])
return (null)
}
Run Code Online (Sandbox Code Playgroud)
用法:
<Router>
<ScrollToTop />
<Switch>
<Route path="/" exact component={Home} />
</Switch>
</Router>
Run Code Online (Sandbox Code Playgroud)
我的解决方案:我在我的屏幕组件中使用的一个组件(我想要滚动到顶部)。
import { useLayoutEffect } from 'react';
const ScrollToTop = () => {
useLayoutEffect(() => {
window.scrollTo(0, 0);
}, []);
return null;
};
export default ScrollToTop;
Run Code Online (Sandbox Code Playgroud)
这会在返回时保留滚动位置。使用 useEffect() 对我来说是有问题的,当返回时,文档会滚动到顶部,并且在已经滚动的文档中更改路由时也会有闪烁的效果。
小智 6
这是我的方法,基于其他人在以前的帖子中所做的。想知道这是否是 2020 年使用位置作为防止重新渲染的依赖项的好方法?
import React, { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
function ScrollToTop( { children } ) {
let location = useLocation();
useEffect( () => {
window.scrollTo(0, 0);
}, [ location ] );
return children
}
Run Code Online (Sandbox Code Playgroud)
具有平滑滚动选项
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
export default function ScrollToTop() {
const { pathname } = useLocation();
useEffect(() => {
window.scrollTo({
top: 0,
left: 0,
behavior: 'smooth',
});
}, [pathname]);
return null;
}
Run Code Online (Sandbox Code Playgroud)
...
<Router>
<ScrollToTop />
...
</Router>
Run Code Online (Sandbox Code Playgroud)
我想为那些正在使用的人分享我的解决方案,react-router-dom v5因为这些 v4 解决方案都没有为我工作。
解决我的问题的是安装react-router-scroll-top并将包装器放在<App />这样的位置:
const App = () => (
<Router>
<ScrollToTop>
<App/>
</ScrollToTop>
</Router>
)
Run Code Online (Sandbox Code Playgroud)
就是这样!有效!
| 归档时间: |
|
| 查看次数: |
45337 次 |
| 最近记录: |