私は問題を抱えています、私は何も考えもしませんが、どのように解決するのか。私の反応コンポーネントでは、データの長いリストと下部にいくつかのリンクを表示します。これらのリンクのどれかをクリックした後、私はリンクの新しいコレクションでリストを埋め、そしてトップにスクロールする必要があります。
問題は - どうやって一番上にスクロールするか 後 新しいコレクションがレンダリングされるのですか?
'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;
最初の解決策は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
最後に..私は使用しました:
componentDidMount() {
window.scrollTo(0, 0)
}
あなたはこのようなものを使うことができます。 ReactDomはreact.14用です。それ以外の場合は反応してください。
componentDidUpdate = () => { ReactDom.findDOMNode(this).scrollIntoView(); }
React 16+のために5/11/2019を更新
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)
}
}
これは refs を使用して処理することができますし、おそらくそうすべきです:
「... ReactDOM.findDOMNodeを「エスケープハッチ」として使用できますが、カプセル化が解除されるためお勧めできません。ほとんどの場合、Reactモデル内でコードを構造化するためのより明確な方法があります。」
コード例:
class MyComponent extends React.Component {
componentDidMount() {
this._div.scrollTop = 0
}
render() {
return <div ref={(ref) => this._div = ref} />
}
}
React Routingでは、新しいルートにリダイレクトしても自動的にページの先頭に移動しないという問題があります。
私にも同じ問題がありました。
私はコンポーネントに単一行を追加しただけで、それはバターのように機能しました。
componentDidMount() {
window.scrollTo(0, 0);
}
参照: 反応トレーニング
あなたはそのようなルータでこれをすることができます:
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
私はreact-routerドキュメントに記述されているコードのreact-router ScrollToTopコンポーネントを使用しています
https://reacttraining.com/react-router/web/guides/scroll-restoration/scroll-to-top
私は1つの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 - App.jsファイルで、<Router
の後にScrollToTopコンポーネントを追加します。
const App = () => (
<Router>
<ScrollToTop>
<App/>
</ScrollToTop>
</Router>
)
ComponentDidUpdate/ComponentDidMountを大量に複製することなく、ウィンドウのスクロール位置をリセットするマウント済みコンポーネントを選択できるようにするもう1つの方法があります。
以下の例では、ブログコンポーネントをScrollIntoView()でラップしているため、ブログコンポーネントがマウントされたときにルートが変更されると、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
メソッドのサンプルコードに変更し、ScrollIntoView
をwithRouter
でラップするだけ)。
container/ScrollIntoView.js
import { PureComponent, Fragment } from "react";
class ScrollIntoView extends PureComponent {
componentDidMount = () => window.scrollTo(0, 0);
render = () => this.props.children
}
export default ScrollIntoView;
components/Home.js
import React from "react";
import ScrollIntoView from "../containers/ScrollIntoView";
export default () => (
<ScrollIntoView>
<div className="container">
<p>
Sample Text
</p>
</div>
</ScrollIntoView>
);
これが私のために働いた唯一のものです(ES6クラスのコンポーネントで):
componentDidMount() {
ReactDOM.findDOMNode(this).scrollIntoView();
}
少なくともクロムで、モバイルに対してこれを実行している場合は、下部に白いバーが表示されます。
これはURLバーが消えたときに起こります。溶液:
Height/min-height:100%のcssをheight/min-height:100vhに変更します。
フックを使用する場合、次のコードが機能します。
React.useEffect(() => {
window.scrollTo(0, 0);
}, []);
また、useEffectを直接インポートすることもできます:import { useEffect } from 'react'
上記のすべてが私にはうまくいきませんでした。
componentDidMount(){
document.getElementById('HEADER').scrollIntoView();
}
hEADERは私のヘッダ要素のIDです
上記の答えのどれも現在私のために働いていません。 .scrollTo
は.scrollIntoView
ほど広くは互換性がありません。
App.jsのcomponentWillMount()
に追加しました
this.props.history.listen((location, action) => {
setTimeout(() => { document.getElementById('root').scrollIntoView({ behavior: "smooth" }) }, 777)
})
これが私たちにとって普遍的に働いている唯一の解決策です。 root
はアプリのIDです。 「滑らかな」動作はすべてのブラウザ/デバイスで機能するわけではありません。 777のタイムアウトは少し保守的ですが、すべてのページに大量のデータをロードするため、テストを通じてこれが必要でした。もっと短い237がほとんどのアプリケーションでうまくいくでしょう。
上記の答えのどれも現在私のために働いていません。 .scrollTo
は.scrollIntoView
ほど広くは互換性がありません。
App.jsのcomponentWillMount()
に追加しました
this.props.history.listen((location, action) => {
setTimeout(() => { document.getElementById('root').scrollIntoView({ behavior: "smooth" }) }, 777)
})
これが私たちにとって普遍的に働いている唯一の解決策です。 rootは我々のアプリのIDです。 「滑らかな」動作はすべてのブラウザ/デバイスで機能するわけではありません。 777のタイムアウトは少し保守的ですが、すべてのページに大量のデータをロードするため、テストを通じてこれが必要でした。もっと短い237がほとんどのアプリケーションでうまくいくでしょう。
このコードは、スクロールでスムーズな動作を引き起こします。
<div onClick={() => {
ReactDOM.findDOMNode(this.headerRef)
.scrollIntoView({behavior: "smooth"});
}}
className='go-up-button' >
</div>
ScrollIntoView()内に他のパラメータを渡すことができます。次の構文を使用できます。
element.scrollIntoView();
element.scrollIntoView(alignToTop); // Boolean parameter
element.scrollIntoView(scrollIntoViewOptions); // Object parameter
alignToTopオプションブール値です。
If true, the top of the element will be aligned to the top of the visible area of the scrollable ancestor. Corresponds to scrollIntoViewOptions: {block: "start", inline: "nearest"}. This is the default value.
If false, the bottom of the element will be aligned to the bottom of the visible area of the scrollable ancestor. Corresponds to scrollIntoViewOptions: {block: "end", inline: "nearest"}.
scrollIntoViewOptionsオプション以下のプロパティを持つオブジェクトです。
*behavior* Optional
Defines the transition animation.
One of "auto", "instant", or "smooth". Defaults to "auto".
*block* Optional
One of "start", "center", "end", or "nearest". Defaults to "center".
*inline* Optional
One of "start", "center", "end", or "nearest". Defaults to "nearest".
詳細はこちらをご覧ください。 MDNドキュメント
すべての解決策は、DOMを使用してcomponentDidMount
またはcomponentDidUpdate
にスクロールを追加することについて説明します。
私はそれをすべてやりましたが、うまくいきませんでした。
だから、私にとってはうまくいく他の方法を考え出した。
ヘッダに
componentDidUpdate() { window.scrollTo(0, 0) }
を追加しました。私のものは<Switch></Switch>
要素の外です。アプリでただ無料。動作します。
ScrollRestoration ことについても見つけましたが、今は怠け者です。そして今のところ、それを "DidUpdate"の方法で続けるつもりです。
それが役に立てば幸い!
安全である
このようなものは私にはコンポーネント上でうまくいきました:
<div ref="scroller" style={{height: 500, overflowX: "hidden", overflowY: "auto"}}>
//Content Here
</div>
それからどんな関数でも更新を扱っています:
this.refs.scroller.scrollTop=0