web-dev-qa-db-ja.com

ReactJSどのように要素までスクロールするか

スクロールするたびに一連のメッセージを表示するチャットウィジェットがあります。私が今直面している問題は、メッセージがロードされるとき、スライダーは一番上に固定されたままで、私はそれが前の配列から最後のインデックス要素に集中して欲しいということです。私はindexを渡すことで動的なrefを作ることができることを考え出しました、しかし私はそれを達成するためにどのような種類のスクロール関数を使うべきかも知っている必要があるでしょう

 handleScrollToElement(event) {
    const tesNode = ReactDOM.findDOMNode(this.refs.test)
    if (some_logic){
      //scroll to testNode      
    }
  }

  render() {

    return (
      <div>
        <div ref="test"></div>
      </div>)
  }
67
edmamerto

オプション1:React.createRefを使用する(React 16.3以降)

class MyComponent extends Component {

    constructor(props) {
        super(props)
        this.myRef = React.createRef()   // Create a ref object 
    }

    render() {
        return <div ref={this.myRef}></div> 
    }   // attach the ref property to a dom element

    scrollToMyRef = () => window.scrollTo(0, this.myRef.current.offsetTop)   
    // run this method to execute scrolling. 

}

オプション2:refコールバックを使う

class MyComponent extends Component {

    constructor(props){   // Optional, declare a class field to improve readability
        super(props)
        this.myRef=null    
    }

    render() {
        return <div ref={ (ref) => this.myRef=ref }></div>
    }   // Attach the dom element to a class field

    scrollToMyRef = () => window.scrollTo(0, this.myRef.offsetTop)
    // run this method to execute scrolling. 
}

文字列参照を使用しないでください。

String refはパフォーマンスに害を及ぼし、構成することはできず、また廃止される予定です(2018年8月)。

文字列参照にはいくつかの問題があり、レガシーと見なされ、将来のリリースの1つで削除される可能性があります。 [公式のReactドキュメント]

resource1resource2

オプション:スクロールアニメーションを滑らかにする

// css
html {
  scroll-behavior: smooth;
}

原則

  1. Refはクラスコンポーネントにのみ格納できます。 (これは将来refフックが解放されたときに変わるでしょう)
  2. 要素までスクロールするには、クラスのrefプロパティを実際のdom要素に添付する必要があります。ブラウザのネイティブスクロール方法を使用しているので、ページ上の要素の実際の位置を知る必要があります。
  3. Ref(上記で提案した方法のいずれかで)は、小道具として子供に渡すことができます。

子供にrefを渡す

React.createRef - refオブジェクトをプロップとして子コンポーネントに渡します。

render() {
    return <ChildComp refProp={this.myRef}></ChildComp>
}

次にref支柱をdom要素に取り付けます。

class ChildComp extends Component {
    render () {
        return <div ref={this.props.refProp} />
    }
}

更新

過去にはoptionsオブジェクトをwindow.scrollToに渡すことをお勧めしました。これにはアニメーションを制御するオプションも含まれています。 EdgeiOSはまだこの形式をサポートしていません。

88
Ben Carp

https://www.w3schools.com/Jsref/prop_element_offsettop.asp そして、scrollTo method https://www.w3schoolsからこの位置までスクロールします。 com/Jsref/met_win_scrollto.asp

このようなものでうまくいくはずです。

handleScrollToElement(event) {
  const tesNode = ReactDOM.findDOMNode(this.refs.test)
  if (some_logic){
    window.scrollTo(0, tesNode.offsetTop);
  }
}

render() {

  return (
    <div>
      <div ref="test"></div>
    </div>)
}

更新:

React v16.3よりReact.createRef()が推奨されます。

constructor(props) {
  super(props);
  this.myRef = React.createRef();
}

handleScrollToElement(event) {
  if (<some_logic>){
    window.scrollTo(0, this.myRef.current.offsetTop);
  }
}

render() {

  return (
    <div>
      <div ref={this.myRef}></div>
    </div>)
}
33
Roman Maksimov

FindDOMNodeの使用は、最終的には推奨されなくなります。

推奨される方法は、コールバック参照を使用することです。

github eslint

14
sww314

scrollIntoViewメソッドを使用して特定の要素までスクロールすることもできます。

handleScrollToElement(event) {
const tesNode = ReactDOM.findDOMNode(this.refs.test)
 if (some_logic){
  tesNode.scrollIntoView();
  }
 }

 render() {
  return (
   <div>
     <div ref="test"></div>
   </div>)
}
9
Farshad J

これは私のために働いた

this.anyRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' })
8
chii

あなたはこのように試すことができます:

 handleScrollToElement = e => {
    const elementTop = this.gate.offsetTop;
    window.scrollTo(0, elementTop);
 };

 render(){
  return(
      <h2 ref={elem => (this.gate = elem)}>Payment gate</h2>
 )}
6

パーティーに間に合わないかもしれませんが、私は自分のプロジェクトに動的な参照を適切な方法で実装しようとしていました。単純で、参照を作成するための反応のネイティブで推奨される方法を使用します。

ドキュメントの作成方法は、既知のビュー数を想定しており、ほとんどの場合、この数は不明なので、問題を解決する方法が必要です。必要な未知のビュー数に対して動的な参照を作成しますクラスに表示する

だから私が考えることができて完璧に働いた最も簡単な解決策は次のようにすることでした。

class YourClass extends component {

state={
 foo:"bar",
 dynamicViews:[],
 myData:[] //get some data from the web
}

inputRef = React.createRef()

componentDidMount(){
  this.createViews()
}


createViews = ()=>{
const trs=[]
for (let i = 1; i < this.state.myData.lenght; i++) {

let ref =`myrefRow ${i}`

this[ref]= React.createRef()

  const row = (
  <tr ref={this[ref]}>
<td>
  `myRow ${i}`
</td>
</tr>
)
trs.Push(row)

}
this.setState({dynamicViews:trs})
}

clickHandler = ()=>{

//const scrollToView = this.inputRef.current.value
//That to select the value of the inputbox bt for demostrate the //example

value=`myrefRow ${30}`

  this[value].current.scrollIntoView({ behavior: "smooth", block: "start" });
}


render(){

return(
<div style={{display:"flex", flexDirection:"column"}}>
<Button onClick={this.clickHandler}> Search</Button>
<input ref={this.inputRef}/>
<table>
<tbody>
{this.state.dynamicViews}
<tbody>
<table>
</div>


)

}

}

export default YourClass

そのようにしてスクロールはあなたが探しているどんな行にも行くでしょう..

応援し、それが他の人に役立つことを願っています

5
Miguel Sedek

componentDidUpdateのようなものを使うことができます

componentDidUpdate() {
  var elem = testNode //your ref to the element say testNode in your case; 
  elem.scrollTop = elem.scrollHeight;
};
5
Raviteja

React hook APIからuseRefを使えるようになりました

https://reactjs.org/docs/hooks-reference.html#useref

宣言

let myRef = useRef()

成分

<div ref={myRef}>My Component</div>

つかいます

window.scrollTo({ behavior: 'smooth', top: myRef.current.offsetTop })

私にとってうまくいったこと:

class MyComponent extends Component {
    constructor(props) {
        super(props);
        this.myRef = React.createRef(); // Create a ref    
    }

    // Scroll to ref function
    scrollToMyRef = () => {
        window.scrollTo({
            top:this.myRef.offsetTop, 
            // behavior: "smooth" // optional
        });
    };

    // On component mount, scroll to ref
    componentDidMount() {
        this.scrollToMyRef();
    }

    // Render method. Note, that `div` element got `ref`.
    render() {
        return (
            <div ref={this.myRef}>My component</div>
        )
    }
}
1

関数構成を使用して実装の詳細を非表示にします

React 16.8 +機能コンポーネント

useScrollフック

次のuseScrollフックは、dom実装の詳細を隠し、シンプルなAPIを提供します。

const useScroll = () => {
  const htmlElRef = useRef(null)
  const executeScroll = () => {
    window.scrollTo(0, htmlElRef.current.offsetTop)
  }

  return [executeScroll, htmlElRef]
}

その後、機能コンポーネントを簡単にスクロールできます。

const ScrollDemo = () => {
    const [executeScroll, elementToScrollRef] = useScroll()

    return (
        <>
            <div ref={elementToScrollRef}>I wanna be seen</div> 
            <button onClick={executeScroll}> Click to scroll </button> 
        </>
    )

}

ここをクリック StackBlitzの完全なデモ

React 16.3 +クラスコンポーネント

utilizeScroll

関数compositioinは、クラスコンポーネントでも使用できます。

const utilizeScroll = () => {
  const htmlElRef = React.createRef()
  const executeScroll = () => {
    window.scrollTo(0, htmlElRef.current.offsetTop)
  }

  return {executeScroll, htmlElRef}
}

次に、任意のクラスコンポーネントで使用します

class ScrollDemo extends Component {
  constructor(){
    this.elScroll = utilizeScroll()
  }
  render(){
        return (
        <> 
          <div ref={this.elScroll.htmlElRef}>I wanna be seen</div> 
          <button onClick={this.elScroll.executeScroll} >Click to scroll </button> 
        </>
      )
  }
} 

ここをクリック StackBlitzの完全なデモ

1
Ben Carp
 <div onScrollCapture={() => this._onScrollEvent()}></div>

 _onScrollEvent = (e)=>{
     const top = e.nativeEvent.target.scrollTop;
     console.log(top); 
}
0
ibamboo