반응 라우터는 모든 전환에서 맨 위로 스크롤합니다.
다른 페이지로 이동할 때 문제가 있습니다. 그 위치는 이전 페이지와 동일하게 유지됩니다. 따라서 자동으로 맨 위로 스크롤되지 않습니다. 나는 또한 window.scrollTo(0, 0)
onChange 라우터 에서 사용하려고했습니다 . 이 문제를 해결하기 위해 scrollBehavior도 사용했지만 작동하지 않았습니다. 이것에 대한 제안이 있습니까?
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)
그런 다음 앱 상단, 라우터 아래에 렌더링합니다.
const App = () => (
<Router>
<ScrollToTop>
<App/>
</ScrollToTop>
</Router>
)
// or just render it bare anywhere you want, but just one :)
<ScrollToTop/>
분명히 이것은 대부분의 경우에 작동하지만 탭 인터페이스를 처리하는 방법과 일반 솔루션이 구현되지 않은 이유에 대해 더 많이 있습니다.
이 답변은 레거시 코드 용이며 라우터 v4 +의 경우 다른 답변 확인
<Router onUpdate={() => window.scrollTo(0, 0)} history={createBrowserHistory()}>
...
</Router>
작동하지 않는 경우 이유를 찾아야합니다. 또한 내부componentDidMount
document.body.scrollTop = 0;
// or
window.scrollTo(0,0);
다음을 사용할 수 있습니다.
componentDidUpdate() {
window.scrollTo(0,0);
}
"scrolled = false"와 같은 플래그를 추가 한 다음 업데이트 할 수 있습니다.
componentDidUpdate() {
if(this.scrolled === false){
window.scrollTo(0,0);
scrolled = true;
}
}
대한 반응 - 라우터 V4 : 여기 스크롤 복원 달성하는 생성 - 반응 - 응용 프로그램입니다 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);
온 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;
위의 코드에서 흥미로운 점은 탐색 할 때만 /about
또는 /another-page
위로 스크롤 작업이 수행된다는 것입니다. 그러나 계속 진행할 때 /
스크롤 복원이 발생하지 않습니다.
전체 코드베이스는 https://github.com/rizedr/react-router-scroll-top 에서 찾을 수 있습니다.
하지만 수업은 너무 2018
React Hooks를 사용한 ScrollToTop 구현
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);
용법:
<Router>
<Fragment>
<ScrollToTop />
<Switch>
<Route path="/" exact component={Home} />
</Switch>
</Fragment>
</Router>
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);
용법:
<Router>
<ScrollToTop>
<Switch>
<Route path="/" exact component={Home} />
</Switch>
</ScrollToTop>
</Router>
이 onUpdate={() => window.scrollTo(0, 0)}
방법이 구식 이라는 것은 주목할 만합니다 .
다음은 react-router 4+에 대한 간단한 해결책입니다.
const history = createBrowserHistory()
history.listen(_ => {
window.scrollTo(0, 0)
})
<Router history={history}>
내 응용 프로그램에서 동일한 문제가 발생했습니다. 아래 코드 스 니펫을 사용하면 다음 버튼을 클릭하면 페이지 상단으로 스크롤 할 수 있습니다.
<Router onUpdate={() => window.scrollTo(0, 0)} history= {browserHistory}>
...
</Router>
그러나 문제는 브라우저에서 여전히 지속되었습니다. 많은 시도 끝에 자동으로 설정된 scrollRestoration 속성이있는 브라우저 창의 히스토리 객체 때문이라는 것을 깨달았습니다. 이것을 수동으로 설정하면 문제가 해결되었습니다.
function scrollToTop() {
window.scrollTo(0, 0)
if ('scrollRestoration' in history) {
history.scrollRestoration = 'manual';
}
}
<Router onUpdate= {scrollToTop} history={browserHistory}>
....
</Router>
나는 withScrollToTop
. 이 HOC는 두 가지 플래그를받습니다.
onComponentWillMount
-탐색시 상단 스크롤 여부 (componentWillMount
)onComponentDidUpdate
-업데이트시 맨 위로 스크롤할지 여부 (componentDidUpdate
). 이 플래그는 구성 요소가 마운트 해제되지 않았지만 탐색 이벤트가 발생하는 경우 (예 : from/users/1
to)에 필요/users/2
합니다.
// @flow
import type { Location } from 'react-router-dom';
import type { ComponentType } from 'react';
import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';
type Props = {
location: Location,
};
type Options = {
onComponentWillMount?: boolean,
onComponentDidUpdate?: boolean,
};
const defaultOptions: Options = {
onComponentWillMount: true,
onComponentDidUpdate: true,
};
function scrollToTop() {
window.scrollTo(0, 0);
}
const withScrollToTop = (WrappedComponent: ComponentType, options: Options = defaultOptions) => {
return class withScrollToTopComponent extends Component<Props> {
props: Props;
componentWillMount() {
if (options.onComponentWillMount) {
scrollToTop();
}
}
componentDidUpdate(prevProps: Props) {
if (options.onComponentDidUpdate &&
this.props.location.pathname !== prevProps.location.pathname) {
scrollToTop();
}
}
render() {
return <WrappedComponent {...this.props} />;
}
};
};
export default (WrappedComponent: ComponentType, options?: Options) => {
return withRouter(withScrollToTop(WrappedComponent, options));
};
그것을 사용하려면 :
import withScrollToTop from './withScrollToTop';
function MyComponent() { ... }
export default withScrollToTop(MyComponent);
여기 또 다른 방법이 있습니다.
대한 반응 라우터 V4 는 역사 이벤트의 변화에 바인드 리스너 수도 있습니다, 다음과 같은 방법으로 :
let firstMount = true;
const App = (props) => {
if (typeof window != 'undefined') { //incase you have server-side rendering too
firstMount && props.history.listen((location, action) => {
setImmediate(() => window.scrollTo(0, 0)); // ive explained why i used setImmediate below
});
firstMount = false;
}
return (
<div>
<MyHeader/>
<Switch>
<Route path='/' exact={true} component={IndexPage} />
<Route path='/other' component={OtherPage} />
// ...
</Switch>
<MyFooter/>
</div>
);
}
//mounting app:
render((<BrowserRouter><Route component={App} /></BrowserRouter>), document.getElementById('root'));
The scroll level will be set to 0 without setImmediate()
too if the route is changed by clicking on a link but if user presses back button on browser then it will not work as browser reset the scroll level manually to the previous level when the back button is pressed, so by using setImmediate()
we cause our function to be executed after browser is finished resetting the scroll level thus giving us the desired effect.
with React router dom v4 you can use
create a scrollToTopComponent component like the one below
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)
or if you are using tabs use the something like the one below
class ScrollToTopOnMount extends Component {
componentDidMount() {
window.scrollTo(0, 0)
}
render() {
return null
}
}
class LongContent extends Component {
render() {
<div>
<ScrollToTopOnMount/>
<h1>Here is my long content page</h1>
</div>
}
}
// somewhere else
<Route path="/long-content" component={LongContent}/>
hope this helps for more on scroll restoration vist there docs hare react router dom scroll restoration
For smaller apps, with 1-4 routes, you could try to hack it with redirect to the top DOM element with #id instead just a route. Then there is no need to wrap Routes in ScrollToTop or using lifecycle methods.
I want to share my solution for those who are using react-router-dom v5
since none of these v4 solutions did the work for me.
What solved my problem was installing react-router-scroll-top and put the wrapper in the like this:
const App = () => (
<Router>
<ScrollToTop>
<App/>
</ScrollToTop>
</Router>
)
and that's it! it worked!
In a component below <Router>
Just add a React Hook (in case you are not using a React class)
React.useEffect(() => {
window.scrollTo(0, 0);
}, [props.location]);
I found that ReactDOM.findDomNode(this).scrollIntoView()
is working. I placed it inside componentDidMount()
.
This is hacky (but works): I just add
window.scrollTo(0,0);
to render();
ReferenceURL : https://stackoverflow.com/questions/36904185/react-router-scroll-to-top-on-every-transition
'programing' 카테고리의 다른 글
브랜치에 포함 된 목록 태그 (0) | 2021.01.06 |
---|---|
null 값이있는 비교기 (0) | 2021.01.06 |
C ++ 배열에 요소를 추가하는 방법은 무엇입니까? (0) | 2021.01.05 |
“===”은 무엇을 의미합니까? (0) | 2021.01.05 |
C 프로그램에서 날짜 및 시간 값을 얻는 방법은 무엇입니까? (0) | 2021.01.05 |