ReactJS how to scroll an element

I have a chat widget that pulls an array of messages every time I scroll up. The problem that I am facing now is that the slider remains fixed at the top when loading messages, I want it to focus on the last index element from the previous array. I realized that I can make dynamic links by passing an index, but I also need to know which scroll function I can use to achieve this.

handleScrollToElement(event) { const tesNode = ReactDOM.findDOMNode(this.refs.test) if (some_logic){ //scroll to testNode } } render() { return ( <div> <div ref="test"></div> </div>) } 
+96
javascript ecmascript-6 reactjs
source share
13 answers

Reaction 16.8+, functional component

 const scrollToRef = (ref) => window.scrollTo(0, ref.current.offsetTop) // General scroll to element function const ScrollDemo = () => { const myRef = useRef(null) const executeScroll = () => scrollToRef(myRef) return ( <> {/* React.Fragment*/} <div ref={myRef}>I wanna be seen</div> <button onClick={executeScroll}> Click to scroll </button> </> ) } 

Click here for a complete demo on StackBlits

Reaction 16.3+, a component of the class

 class ReadyToScroll 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. } 

Class Component - Callback Link

 class ReadyToScroll 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. } 

Do not use string links.

String links are detrimental to performance, unlinkable, and are on the way out (August 2018).

String links have some problems, are deprecated, and may be removed in a future release. [React official documentation]

resource1 resource2

Optional: Smooth scroll animation

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

Passing a link to a child

We want the link to be attached to the dom element, and not to the reaction component. Thus, passing it to the child component, we cannot name the reference ref.

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

Then attach the support element to the dom element.

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

Just find the top position of the element that you already defined https://www.w3schools.com/Jsref/prop_element_offsettop.asp, then scrollTo to that position using the scrollTo method https://www.w3schools.com/Jsref/met_win_scrollto. viper

Something like this should work:

 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>) } 

UPDATE:

since React v16.3, React.createRef() is preferred

 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
source share

it worked for me

 this.anyRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' }) 
+18
source share

Using findDOMNode will eventually be deprecated.

The preferred method is to use backlinks.

Github eslint

+14
source share

You can also use the scrollIntoView method to scroll to a specific item.

 handleScrollToElement(event) { const tesNode = ReactDOM.findDOMNode(this.refs.test) if (some_logic){ tesNode.scrollIntoView(); } } render() { return ( <div> <div ref="test"></div> </div>) } 
+9
source share

Maybe I was late for the party, but I tried to correctly implement dynamic links in my project, and all the answers that I found until I found out did not satisfy my taste, so I found a solution that seems simple to me and uses the native and recommended response method to create the link.

sometimes you find that when writing documentation it is assumed that you have a known number of views, and in most cases this number is unknown, so in this case you need a way to solve the problem, create dynamic links to an unknown number of views that you need to show in the class

therefore, the simplest solution that I could come up with and work flawlessly was as follows

 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 

This way, the scroll will go to any line you are looking for ..

cheers and hope this helps others

+7
source share

You can try this:

  handleScrollToElement = e => { const elementTop = this.gate.offsetTop; window.scrollTo(0, elementTop); }; render(){ return( <h2 ref={elem => (this.gate = elem)}>Payment gate</h2> )} 
+6
source share

Now you can use useRef from the reaction hook API

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

declaration

 let myRef = useRef() 

component

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

Using

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

You can use something like componentDidUpdate

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

Use function composition to hide implementation details

Reaction 16.8 + functional component

useScroll hook

The following useScroll hook hides the details of the dom implementation and provides a simple API.

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

Then you can easily scroll through your functional components.

 const ScrollDemo = () => { const [executeScroll, elementToScrollRef] = useScroll() return ( <> <div ref={elementToScrollRef}>I wanna be seen</div> <button onClick={executeScroll}> Click to scroll </button> </> ) } 

Click here for a full demo on StackBlitz

Responsive 16.3 + Grade Component

utilizeScroll

The compositioin function can also be used in class components.

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

Then use it in any component of the class

 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> </> ) } } 

Click here for a full demo on StackBlitz

+2
source share

What worked for me:

 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
source share

After testing several solutions, scroll through the list of components.
Using $ inside the Component class, it still allows scrolling to be applied to any element using the xpath selector.

 import React from 'react'; import $ from "jquery" scrollToElem() { var elem= $( ".selector" )[0]; $('html, body').animate({ scrollTop: $(elem).offset().top }, 1800); } 
0
source share
  <div onScrollCapture={() => this._onScrollEvent()}></div> _onScrollEvent = (e)=>{ const top = e.nativeEvent.target.scrollTop; console.log(top); } 
0
source share

All Articles