web-dev-qa-db-ja.com

react.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;
105

最初の解決策は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
50

最後に..私は使用しました:

componentDidMount() {
  window.scrollTo(0, 0)
}
197
lxm7

あなたはこのようなものを使うことができます。 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)
    }
  }
37
J. Mark Stevens

これは refs を使用して処理することができますし、おそらくそうすべきです:

「... ReactDOM.findDOMNodeを「エスケープハッチ」として使用できますが、カプセル化が解除されるためお勧めできません。ほとんどの場合、Reactモデル内でコードを構造化するためのより明確な方法があります。」

コード例:

class MyComponent extends React.Component {
    componentDidMount() {
        this._div.scrollTop = 0
    }

    render() {
        return <div ref={(ref) => this._div = ref} />
    }
}
13
GGAlanSmithee

React Routingでは、新しいルートにリダイレクトしても自動的にページの先頭に移動しないという問題があります。

私にも同じ問題がありました。

私はコンポーネントに単一行を追加しただけで、それはバターのように機能しました。

componentDidMount() {
    window.scrollTo(0, 0);
}

参照: 反応トレーニング

11
Vishal Shetty

あなたはそのようなルータでこれをすることができます:

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

9

私は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>
)
6
Arpit

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メソッドのサンプルコードに変更し、ScrollIntoViewwithRouterでラップするだけ)。

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>
);
6
Matt Carlotta

これが私のために働いた唯一のものです(ES6クラスのコンポーネントで):

componentDidMount() {
  ReactDOM.findDOMNode(this).scrollIntoView();
}
5
danharsanyi

少なくともクロムで、モバイルに対してこれを実行している場合は、下部に白いバーが表示されます。

これはURLバーが消えたときに起こります。溶液:

Height/min-height:100%のcssをheight/min-height:100vhに変更します。

Google Developer Docs

2
Artur Carvalho

フックを使用する場合、次のコードが機能します。

React.useEffect(() => {
  window.scrollTo(0, 0);
}, []);

また、useEffectを直接インポートすることもできます:import { useEffect } from 'react'

2
Powderham

上記のすべてが私にはうまくいきませんでした。

componentDidMount(){
    document.getElementById('HEADER').scrollIntoView();
}

hEADERは私のヘッダ要素のIDです

1
James Shiztar

上記の答えのどれも現在私のために働いていません。 .scrollTo.scrollIntoViewほど広くは互換性がありません。

App.jsのcomponentWillMount()に追加しました

    this.props.history.listen((location, action) => {
            setTimeout(() => { document.getElementById('root').scrollIntoView({ behavior: "smooth" }) }, 777)
        })

これが私たちにとって普遍的に働いている唯一の解決策です。 rootはアプリのIDです。 「滑らかな」動作はすべてのブラウザ/デバイスで機能するわけではありません。 777のタイムアウトは少し保守的ですが、すべてのページに大量のデータをロードするため、テストを通じてこれが必要でした。もっと短い237がほとんどのアプリケーションでうまくいくでしょう。

0
Todd

上記の答えのどれも現在私のために働いていません。 .scrollTo.scrollIntoViewほど広くは互換性がありません。

App.jsのcomponentWillMount()に追加しました

this.props.history.listen((location, action) => {
        setTimeout(() => { document.getElementById('root').scrollIntoView({ behavior: "smooth" }) }, 777)
    })

これが私たちにとって普遍的に働いている唯一の解決策です。 rootは我々のアプリのIDです。 「滑らかな」動作はすべてのブラウザ/デバイスで機能するわけではありません。 777のタイムアウトは少し保守的ですが、すべてのページに大量のデータをロードするため、テストを通じてこれが必要でした。もっと短い237がほとんどのアプリケーションでうまくいくでしょう。

0
Todd

このコードは、スクロールスムーズな動作を引き起こします。

<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ドキュメント

0
Abhay Shiro

すべての解決策は、DOMを使用してcomponentDidMountまたはcomponentDidUpdateにスクロールを追加することについて説明します。

私はそれをすべてやりましたが、うまくいきませんでした。

だから、私にとってはうまくいく他の方法を考え出した。

ヘッダにcomponentDidUpdate() { window.scrollTo(0, 0) }を追加しました。私のものは<Switch></Switch>要素の外です。アプリでただ無料。動作します。

ScrollRestoration ことについても見つけましたが、今は怠け者です。そして今のところ、それを "DidUpdate"の方法で続けるつもりです。

それが役に立てば幸い!

安全である

0
Buzzcut Season

このようなものは私にはコンポーネント上でうまくいきました:

<div ref="scroller" style={{height: 500, overflowX: "hidden", overflowY: "auto"}}>
      //Content Here
</div>

それからどんな関数でも更新を扱っています:

this.refs.scroller.scrollTop=0
0
kojow7