How to scroll to an element?

edmamerto picture edmamerto · Apr 16, 2017 · Viewed 327.4k times · Source

I have a chat widget that pulls up an array of messages every time I scroll up. The problem I am facing now is the slider stays fixed at the top when messages load. I want it to focus on the last index element from the previous array. I figured out that I can make dynamic refs by passing index, but I would also need to know what kind of scroll function to use to achieve that

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

  render() {

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

Answer

Ben Carp picture Ben Carp · Aug 13, 2018

React 16.8 +, Functional component

const ScrollDemo = () => {
   const myRef = useRef(null)

   const executeScroll = () => myRef.current.scrollIntoView()    
   // run this function from an event handler or an effect to execute scroll 

   return (
      <> 
         <div ref={myRef}>Element to scroll to</div> 
         <button onClick={executeScroll}> Click to scroll </button> 
      </>
   )
}

Click here for a full demo on StackBlits

React 16.3 +, Class component

class ReadyToScroll extends Component {
    constructor(props) {
        super(props)
        this.myRef = React.createRef()  
    }

    render() {
        return <div ref={this.myRef}>Element to scroll to</div> 
    }  

    executeScroll = () => this.myRef.current.scrollIntoView()
    // run this method to execute scrolling. 
}

Class component - Ref callback

class ReadyToScroll extends Component {  
    render() {
        return <div ref={ (ref) => this.myRef=ref }>Element to scroll to</div>
    } 

    executeScroll = () => this.myRef.scrollIntoView()
    // run this method to execute scrolling. 
}

Don't use String refs.

String refs harm performance, aren't composable, and are on their way out (Aug 2018).

string refs have some issues, are considered legacy, and are likely to be removed in one of the future releases. [Official React documentation]

resource1resource2

Optional: Smoothe scroll animation

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

Passing ref to a child

We want the ref to be attached to a dom element, not to a react component. So when passing it to a child component we can't name the prop ref.

const MyComponent = () => {
    const myRef = useRef(null)
    return <ChildComp refProp={myRef}></ChildComp>
} 

Then attach the ref prop to a dom element.

const ChildComp = (props) => {
    return <div ref={props.refProp} />
}