React, Using Refs to scrollIntoView() doen't work on componentDidUpdate()

16,952

Ok it's been a while but I got it working in another project without the setTimeOut function so I wanted to answer this question. Since Redux pass the new updates through props, I used the componentWillRecieveProps() method instead of componentDidUpdate() , this allowes you a better control over the updated properties and works as expected with the scrollIntoView() function.

class PhotoContainer extends React.Component {

  componentWillReceiveProps(newProps) {
    if (
      this.props.navigation.sectionSelected !==
        newProps.navigation.sectionSelected &&
      newProps.navigation.sectionSelected !== ""
    ) {
      this.focusDiv(newProps.navigation.sectionSelected);
    }
  }

  focusDiv(section){
    var scrolling = this[section]; //section would be 'theDiv' in this example
    scrolling.scrollIntoView({ block: "start", behavior: "smooth" });//corrected typo
  }

  render() {
    const totalList = [];
    for(let i = 0; i < 300; i += 1) {
        totalList.push(
            <div key={i}>{`hello ${i}`}</div>
        );
    }

    return (
      <div >
          {totalList}
          <div ref={(el) => this.theDiv = el}>
            this is the div I am trying to scroll to
          </div>
       </div>
         )
      };
    }
Share:
16,952

Related videos on Youtube

RamiroIsBack
Author by

RamiroIsBack

I live in Baltimore MD. Coding mainly in ReactJS I have few projects up and running already. Check out my resume here: https://rrsa-developer.herokuapp.com/

Updated on September 15, 2022

Comments

  • RamiroIsBack
    RamiroIsBack almost 2 years

    I'm using Redux in my app, inside a Component I want to scroll to an specific div tag when a change in the store happens. I have the Redux part working so it triggers the componentDidUpdate() method (I routed to this compoennt view already). The problem as far as I can tell, is that the method scrollIntoView() doesn't work properly cos componentDidUpdate() has a default behavior that scrolls to the top overwriting the scrollIntoView(). To work-around it I wrapped the function calling scrollIntoView() in a setTimeout to ensure that happens afeterwards. What I would like to do is to call a preventDefault() or any other more elegant solution but I can't find where to get the event triggering the 'scrollTop' I looked through the Doc here: https://facebook.github.io/react/docs/react-component.html#componentdidupdate and the params passed in this function are componentDidUpdate(prevProps, prevState) ,since there is no event I don't know how to call preventDefault()

    I've followd this Docs: https://facebook.github.io/react/docs/refs-and-the-dom.html And tried different approaches people suggested here: How can I scroll a div to be visible in ReactJS?

    Nothing worked though Here is my code if anyone has any tip for me, thanks

    class PhotoContainer extends React.Component {
    
      componentDidUpdate(){
        setTimeout(() => {
         this.focusDiv();
        }, 500);
    
      }
      focusDiv(){
        var scrolling = this.theDiv;
        scrolling.scrollIntoView();
    
      }
    
      render() {
        const totalList = [];
        for(let i = 0; i < 300; i += 1) {
            totalList.push(
                <div key={i}>{`hello ${i}`}</div>
            );
        }
    
      return (
          <div >
              {totalList}
              <div ref={(el) => this.theDiv = el}>this is the div I'm trying to scroll to</div>
          </div>
      )
    

    }; }

    • Finbarr O'B
      Finbarr O'B almost 7 years
      The simplest truthy check is to do if(input){ this.textInput = input; }, but I suspect this isn't your problem. I've just tried to run your code, and it appears to work in my case. I had to include componentDidMount() however as I was not manipulating state anywhere in my component (componentDidUpdate() is only called if the component state is changed). I also removed the bootstrap CSS classes. See here: github.com/finbarrobrien/reacty/blob/master/src/App.js
    • Finbarr O'B
      Finbarr O'B
      Also, it may help to check if 'input' is truthy in your ref callback, remember the ref is called with the element on mount and null on unmount (facebook.github.io/react/docs/refs-and-the-dom.html)
    • Finbarr O'B
      Finbarr O'B
      Are you sure scrollIntoView is supported on the browser version you are using? developer.mozilla.org/en/docs/Web/API/Element/…
  • agravat.in
    agravat.in about 4 years
    I am using functional component so cannot use componentWillRecieveProps so i am using setTimeOut with 0. and thank you for tip :)