resact.js로 렌더링한 후 페이지 맨 위로 스크롤합니다.
어떻게 풀어야 할지 모르는 문제가 있어요.리액션 컴포넌트에서는 데이터 목록이 길고 링크 수가 적습니다.이 링크 중 하나를 클릭하면 목록에 링크의 새로운 컬렉션을 입력하고 맨 위로 스크롤해야 합니다.
문제는 새 컬렉션을 렌더링한 후 맨 위로 스크롤하려면 어떻게 해야 합니까?
'use strict';
// url of this component is #/:checklistId/:sectionId
var React = require('react'),
Router = require('react-router'),
sectionStore = require('./../stores/checklist-section-store');
function updateStateFromProps() {
var self = this;
sectionStore.getChecklistSectionContent({
checklistId: this.getParams().checklistId,
sectionId: this.getParams().sectionId
}).then(function (section) {
self.setState({
section,
componentReady: true
});
});
this.setState({componentReady: false});
}
var Checklist = React.createClass({
mixins: [Router.State],
componentWillMount: function () {
updateStateFromProps.call(this);
},
componentWillReceiveProps(){
updateStateFromProps.call(this);
},
render: function () {
if (this.state.componentReady) {
return(
<section className='checklist-section'>
<header className='section-header'>{ this.state.section.name } </header>
<Steps steps={ this.state.section.steps }/>
<a href=`#/${this.getParams().checklistId}/${this.state.section.nextSection.Id}`>
Next Section
</a>
</section>
);
} else {...}
}
});
module.exports = Checklist;
드디어...사용:
componentDidMount() {
window.scrollTo(0, 0)
}
편집: 리액트 v16.8+
useEffect(() => {
window.scrollTo(0, 0)
}, [])
초기 버전의 react를 위해 원래 솔루션이 제공되었으므로, 다음은 업데이트입니다.
constructor(props) {
super(props)
this.myRef = React.createRef() // Create a ref object
}
componentDidMount() {
this.myRef.current.scrollTo(0, 0);
}
render() {
return <div ref={this.myRef}></div>
} // attach the ref property to a dom element
이런 게 필요할 거야ReactDom은 react.14를 위한 것입니다.그렇지 않으면 반응하세요.
componentDidUpdate = () => { ReactDom.findDOMNode(this).scrollIntoView(); }
React 16+용 업데이트(2019년 5월 11일)
constructor(props) {
super(props)
this.childDiv = React.createRef()
}
componentDidMount = () => this.handleScroll()
componentDidUpdate = () => this.handleScroll()
handleScroll = () => {
const { index, selected } = this.props
if (index === selected) {
setTimeout(() => {
this.childDiv.current.scrollIntoView({ behavior: 'smooth' })
}, 500)
}
}
리액트 라우팅에서는 새로운 루트로 리다이렉트해도 자동으로 페이지 맨 위로 이동하지 않는 문제가 있습니다.
나조차도 같은 문제를 안고 있었다.
부품에 한 줄만 추가했는데 버터처럼 작동했어요.
componentDidMount() {
window.scrollTo(0, 0);
}
후크 솔루션:
- ScrollToTop 훅 만들기
import { useEffect } from "react";
import { withRouter } from "react-router-dom";
const ScrollToTop = ({ children, location: { pathname } }) => {
useEffect(() => {
window.scrollTo({
top: 0,
left: 0,
behavior: "smooth"
});
}, [pathname]);
return children || null;
};
export default withRouter(ScrollToTop);
- 앱 포장
<Router>
<ScrollToTop>
<App />
</ScrollToTop>
</Router>
문서: https://reacttraining.com/react-router/web/guides/scroll-restoration
후크를 사용하고 있는 유저에게는, 다음의 코드가 유효합니다.
React.useEffect(() => {
window.scrollTo(0, 0);
}, []);
useEffect를 가져올 수도 있습니다.import { useEffect } from 'react'
이는 참조를 사용하여 처리할 수 있으며, 아마도 처리해야 합니다.
"...ReactDOM.findDOMName을 "회피 해치"로 사용할 수 있지만 캡슐화가 깨지고 거의 모든 경우에 React 모델 내에서 코드를 구조화할 수 있는 더 명확한 방법이 있으므로 권장하지 않습니다."
코드 예:
class MyComponent extends React.Component {
componentDidMount() {
this._div.scrollTop = 0
}
render() {
return <div ref={(ref) => this._div = ref} />
}
}
다음과 같이 라우터에서 실행할 수 있습니다.
ReactDOM.render((
<Router onUpdate={() => window.scrollTo(0, 0)} history={browserHistory}>
<Route path='/' component={App}>
<IndexRoute component={Home}></IndexRoute>
<Route path="/about" component={About}/>
<Route path="/work">
<IndexRoute component={Work}></IndexRoute>
<Route path=":id" component={ProjectFull}></Route>
</Route>
<Route path="/blog" component={Blog}/>
</Route>
</Router>
), document.getElementById('root'));
onUpdate={() => window.scrollTo(0, 0)}
스크롤 탑을 놓습니다.자세한 내용은 codepen link를 참조하십시오.
난 이거면 돼.
import React, { useEffect } from 'react';
useEffect(() => {
const body = document.querySelector('#root');
body.scrollIntoView({
behavior: 'smooth'
}, 500)
}, []);
ComponentDidUpdate/ComponentDidMount를 대량 복제하지 않고 창 스크롤 위치를 재설정할 마운트된 구성 요소를 선택할 수 있는 또 다른 방법이 있습니다.
다음 예시는 Blog 컴포넌트를 ScrollIntoView()로 래핑하고 있습니다.이로 인해 Blog 컴포넌트가 마운트되었을 때 루트가 변경되면 HOC의 ComponentDidUpdate가 창 스크롤 위치를 업데이트합니다.
전체 앱에서 쉽게 래핑할 수 있으므로 경로 변경 시 윈도우 리셋을 트리거할 수 있습니다.
ScrollIntoView.js
import React, { Component } from 'react';
import { withRouter } from 'react-router';
export default WrappedComponent => {
class ResetWindowScroll extends Component {
componentDidUpdate = (prevProps) => {
if(this.props.location !== prevProps.location) window.scrollTo(0,0);
}
render = () => <WrappedComponent {...this.props} />
}
return withRouter(ResetWindowScroll);
}
Routes.js
import React from 'react';
import { Route, IndexRoute } from 'react-router';
import App from '../components/App';
import About from '../components/pages/About';
import Blog from '../components/pages/Blog'
import Index from '../components/Landing';
import NotFound from '../components/navigation/NotFound';
import ScrollIntoView from '../components/navigation/ScrollIntoView';
export default (
<Route path="/" component={App}>
<IndexRoute component={Index} />
<Route path="/about" component={About} />
<Route path="/blog" component={ScrollIntoView(Blog)} />
<Route path="*" component={NotFound} />
</Route>
);
는 매우로하고 .react-router-dom
위의 할 수 HOC
컴포넌트를 감싼다.
한 번, 마찬가지로 쉽게 할 수 만 하면 ).componentDidMount
의 메서드componentDidUpdate
및 랩핑 " " method method method method method method method method method 。ScrollIntoView
withRouter
를 참조해 주세요.
컨테이너/ScrollIntoView.js
import { PureComponent, Fragment } from "react";
class ScrollIntoView extends PureComponent {
componentDidMount = () => window.scrollTo(0, 0);
render = () => this.props.children
}
export default ScrollIntoView;
컴포넌트/Home.js
import React from "react";
import ScrollIntoView from "../containers/ScrollIntoView";
export default () => (
<ScrollIntoView>
<div className="container">
<p>
Sample Text
</p>
</div>
</ScrollIntoView>
);
이 솔루션은 기능 컴포넌트 및 클래스 베이스에서 동작합니다.
우선, 모든 리렌더에 Scroll to top을 붙이는 것은 싫고, 대신 특정 이벤트에 부가 기능을 붙이는 것이 좋습니다.
순서 1: ScrollToTop으로 기능 생성
const scrollToTop = () => {
window.scrollTo({
top: 0,
behavior: "smooth",
});
};
이이 함수는 2: 이 함수로 호출합니다.event
: ★onClick
onRowClick={scrollToTop()}
// onClick={scrollToTop()}
// etc...
리액트 라우터 문서에 설명된 코드인 리액트 라우터 ScrollToTop 컴포넌트를 사용하고 있습니다.
https://reacttraining.com/react-router/web/guides/scroll-restoration/scroll-to-top
단일 Routes 파일에서 코드를 변경하고 그 이후에는 모든 컴포넌트에서 코드를 변경할 필요가 없습니다.
코드 예시 -
순서 1 - ScrollToTop.js 컴포넌트 작성
import React, { Component } from 'react';
import { withRouter } from 'react-router';
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)
2 - 를 2 - App.js "ScrollToTop" 뒤에 합니다.<Router
const App = () => (
<Router>
<ScrollToTop>
<App/>
</ScrollToTop>
</Router>
)
모든 것이 간단한 것이라면, 여기에서는 모든 사람에게 효과가 있는 솔루션이 있습니다.
이 미니 기능을 추가하다
scrollTop()
{
window.scrollTo({
top: 0,
behavior: "smooth"
});
}
페이지 바닥글에서 다음과 같이 함수를 호출한다.
<a className="scroll-to-top rounded" style={{display: "inline"}} onClick={this.scrollTop}>TOP</a>
여기에 멋진 스타일을 더하고 싶다면 css입니다.
.scroll-to-top {
position: fixed;
right: 1rem;
bottom: 1rem;
display: none;
width: 2.75rem;
height: 2.75rem;
text-align: center;
color: #fff;
background: rgba(90, 92, 105, 0.5);
line-height: 46px;
}
이것이 유일하게 기능한 것입니다(ES6 클래스 컴포넌트).
componentDidMount() {
ReactDOM.findDOMNode(this).scrollIntoView();
}
위의 모든 것이 나에게는 효과가 없었습니다.왜 그런지 모르겠지만:
componentDidMount(){
document.getElementById('HEADER').scrollIntoView();
}
HEADER는 헤더 요소의 ID입니다.
@sledgeweight 솔루션을 시도했지만 일부 뷰에서는 잘 작동하지 않습니다.그러나 set Timeout을 추가하는 것은 완벽하게 작동하는 것 같습니다.누군가 나와 같은 문제에 직면했을 때를 대비해서.아래는 제 코드입니다.
import { useEffect } from 'react'
import { useLocation } from 'react-router-dom'
const ScrollToTop = () => {
const { pathname } = useLocation()
useEffect(() => {
console.log(pathname)
/* settimeout make sure this run after components have rendered. This will help fixing bug for some views where scroll to top not working perfectly */
setTimeout(() => {
window.scrollTo({ top: 0, behavior: 'smooth' })
}, 0)
}, [pathname])
return null
}
export default ScrollToTop
AppRouter.js에서 사용:
<Router>
<ScrollToTop/>
<App>
</Router>
기능 컴포넌트에서 후크를 사용하여 결과 소품에서 업데이트가 있을 때 컴포넌트가 업데이트된다고 가정합니다.
import React, { useEffect } from 'react';
export const scrollTop = ({result}) => {
useEffect(() => {
window.scrollTo(0, 0);
}, [result])
}
클릭 후에 표시되는 페이지는, 거기에 기입하기만 하면 됩니다.
componentDidMount() {
window.scrollTo(0, 0);
}
맨 위로 부드럽게 스크롤합니다.후크에서는 이 방법을 라이프 사이클 마운트 상태 내에서 한 번 렌더링할 수 있습니다.
useEffect(() => {
window.scrollTo({top: 0, left: 0, behavior: 'smooth' });
}, [])
모든 useEffect 예제는 고려되지 않는 것으로 보입니다.상태 변경으로 트리거할 수 있습니다.
const [aStateVariable, setAStateVariable] = useState(false);
const handleClick = () => {
setAStateVariable(true);
}
useEffect(() => {
if(aStateVariable === true) {
window.scrollTo(0, 0)
}
}, [aStateVariable])
다 해봤지만 이것밖에 안 먹혔어요.
useLayoutEffect(() => {
document.getElementById("someID").scrollTo(0, 0);
});
제가 한 일은 다음과 같습니다.
useEffect(() => ref.current.scrollTo(0, 0));
const ref = useRef()
return(
<div ref={ref}>
...
</div>
)
기능 컴포넌트와 window.scroll, window.scrollTo를 사용하여 React 17.0에서 SPA를 실행 중이었는데 이 모든 변종에서 문제가 발생하였습니다.그래서 저는 useRef 훅을 사용하여 해결책을 만들었습니다.Ref를 사용하여 컴포넌트 상단에 스판 태그를 만들고 ref.current.scrollIntoView()를 사용하여 유효하게 했습니다.
간단한 예를 다음에 제시하겠습니다.
import React, { useEffect,useRef} from 'react';
export const ExampleComponent = () => {
const ref = useRef();
useEffect(() => {
ref.current.scrollIntoView()
}, []);
return(
<>
<span ref={ref}></span>
<YourCodeHere />
<MoreCode />
</>
) }
React Hooks를 사용하고 있는데, 재사용 가능한 것뿐만 아니라 렌더링 직후가 아니라 언제든지 호출할 수 있는 것을 원했습니다.
// utils.js
export const useScrollToTop = (initialScrollState = false) => {
const [scrollToTop, setScrollToTop] = useState(initialScrollState);
useEffect(() => {
if (scrollToTop) {
setScrollToTop(false);
try {
window.scroll({
top: 0,
left: 0,
behavior: 'smooth',
});
} catch (error) {
window.scrollTo(0, 0);
}
}
}, [scrollToTop, setScrollToTop]);
return setScrollToTop;
};
후크를 사용하려면 다음 작업을 수행합니다.
import { useScrollToTop } from 'utils';
const MyPage = (props) => {
// initialise useScrollToTop with true in order to scroll on page load
const setScrollToTop = useScrollToTop(true);
...
return <div onClick={() => setScrollToTop(true)}>click me to scroll to top</div>
}
나는 Reach Router 위에 링크가 구축되어 있는 Gatsby와 사이트를 구축하면서 이 문제에 부딪쳤다.이것이 기본 동작보다는 수정되어야 하는 것이 이상하다고 생각됩니다.
어쨌든, 저는 위의 많은 솔루션을 시도해 보았습니다만, 실제로 효과가 있었던 것은 다음과 같습니다.
document.getElementById("WhateverIdYouWantToScrollTo").scrollIntoView()
useEffect에 넣었지만 componentDidMount에 넣거나 원하는 방식으로 트리거할 수 있습니다.
window.scrollTo(0, 0)가 왜 다른 사람에게 작동하지 않는지 모르겠습니다.
저도 한동안 같은 문제를 안고 있었어요.모든 페이지에 window.scrollTo(0, 0)를 추가하는 것은 번거롭고 장황합니다.따라서 모든 루트를 랩핑하여 BrowserRouter 컴포넌트 내에 머무르는 HOC를 추가했습니다.
<ScrollTop>
<Routes />
</ScrollTop>
ScrollTopComponent 내부에는 다음이 있습니다.
import React, { useEffect } from "react";
import { useLocation } from "react-router-dom";
const ScrollTop = (props) => {
const { children } = props;
const location = useLocation();
useEffect(() => {
window.scrollTo(0, 0);
}, [location]);
return <main>{children}</main>;
};
export default ScrollTop;
기능 컴포넌트 솔루션 - useEffect() 후크 사용
useEffect(() => {
window.history.scrollRestoration = 'manual';}, []);
React v18+의 경우 래퍼 컴포넌트를 사용하는 것이 가장 쉬운 실행 방법입니다.
순서 1: ScrollToTop 컴포넌트(컴포넌트/ScrollToTop.js)를 만듭니다.
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
export function ScrollToTop() {
const { pathname } = useLocation();
useEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);
return null;
}
2단계: 앱을 랩핑(index.js)
<React.StrictMode>
<BrowserRouter>
<ScrollToTop />
<App />
</BrowserRouter>
</React.StrictMode>
설명:경로 이름이 변경될 때마다 useEffect가 호출되어 페이지가 맨 위로 스크롤됩니다.
적어도 크롬을 사용하는 모바일용이라면 하단에 흰색 막대가 표시됩니다.
이 문제는 URL 표시줄이 사라지면 발생합니다.솔루션:
높이/최소 높이:100%를 높이/최소 높이:100vh로 변경합니다.
위의 답변 중 어느 것도 현재 나에게는 효과가 없습니다. 보니, ★★★★★★★★★★★★★★★★★★..scrollTo
할 수 .scrollIntoView
.
App.js에서는componentWillMount()
추가했습니다
this.props.history.listen((location, action) => {
setTimeout(() => { document.getElementById('root').scrollIntoView({ behavior: "smooth" }) }, 777)
})
이것은 우리에게 보편적으로 기능하는 유일한 솔루션입니다.root은 우리 앱의 ID입니다."스무스" 동작은 모든 브라우저/디바이스에서 동작하는 것은 아닙니다.777 타임아웃은 다소 보수적이지만 모든 페이지에 많은 데이터를 로드하기 때문에 테스트를 통해 이것이 필요했습니다.대부분의 어플리케이션에서는 짧은 237이 유효할 수 있습니다.
언급URL : https://stackoverflow.com/questions/33188994/scroll-to-the-top-of-the-page-after-render-in-react-js
'your programing' 카테고리의 다른 글
WooCommerce 함수에 WP/WC 인수 누락 (0) | 2023.04.02 |
---|---|
지시 템플릿 내의 DOM 요소에 액세스하는 AngularJS (0) | 2023.04.02 |
AngularJS는 2000개 정도의 요소를 사용하여 렌더링하는 데 시간이 많이 걸립니까? (0) | 2023.04.02 |
Fabric.js - 커스텀 속성을 사용하여 서버에 캔버스를 저장하는 방법 (0) | 2023.04.02 |
워드프레스 루프 표시 제한 게시물 (0) | 2023.04.02 |