4

Have a look at this pen: https://codepen.io/segmentationfaulter/pen/XzgJyV

I am also pasting the code here for convenience. Upon opening the pen above, you will see that a slider is rendered. Scroll the slider right, and the click on change slides button, you will see that slider is re-rendered with different numbers, but the scroll position of the slider is not reset. Why is the scroll position not reset? Thanks

function SliderElement({
  elementContent
}) {
  return ( <
    div className = 'slider-element' > {
      elementContent
    } < /div>
  )
}

class Slider extends React.Component {
    render() {
        return ( <
          div className = 'slider' > {
            this.props.sliderContentArray.map(elementContent => < SliderElement elementContent = {
                elementContent
              }
              />)} <
              /div>
            )
          }
        }

        class SliderContainer extends React.Component {
          constructor() {
            super()
            this.slidersContent = [
              [1, 2, 3, 4, 5, 6, 7, 8],
              [9, 10, 11, 12, 13, 14, 15, 16]
            ]

            this.state = {
              currentSliderIndex: 0
            }
          }
          switchSlider() {
            this.setState((prevState) => {
              if (prevState.currentSliderIndex === 0) {
                return {
                  currentSliderIndex: 1
                }
              } else {
                return {
                  currentSliderIndex: 0
                }
              }
            })
          }
          render() {
            return ( <
              div >
              <
              Slider sliderContentArray = {
                this.slidersContent[this.state.currentSliderIndex]
              }
              /> <
              button className = 'slider-switch-button'
              onClick = {
                this.switchSlider.bind(this)
              } >
              change slides <
              /button> <
              /div>
            )
          }
        }

        ReactDOM.render( <
          SliderContainer / > ,
          document.getElementById('root')
        );
.slider {
  display: flex;
  overflow: scroll;
}

.slider-element {
  flex-shrink: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 20%;
  height: 100px;
  background: yellow;
}

.slider-element+.slider-element {
  margin-left: 10px;
}

.slider-switch-button {
  margin-top: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Dane
  • 9,242
  • 5
  • 33
  • 56
Muhammad Saqib
  • 1,037
  • 3
  • 10
  • 16
  • 2
    Possible duplicate of [Scroll to the top of the page after render in react.js](https://stackoverflow.com/questions/33188994/scroll-to-the-top-of-the-page-after-render-in-react-js) – Dane Nov 14 '17 at 09:16

3 Answers3

3

You need to manually update the scroll position using the scrollLeft property each time the component is updated. You can do this inside the componentDidUpdate of the Slider component:

  componentDidUpdate() {
    ReactDOM.findDOMNode(this).scrollLeft = 0;
  }

Find the working pen here: https://codepen.io/danegit/pen/xPrayY?editors=0010

Dane
  • 9,242
  • 5
  • 33
  • 56
3

you can use a generic solution for that issue

export const history = createHistory()

history.listen((location, action) => {
    window.scrollTo(0, 0)
})

with this listener, you can "observe" every change in the routes

Source: https://medium.com/@nasir/reset-scroll-position-on-change-of-routes-react-a0bd23093dfe#

1

Your Slider Content rerenders but the scrollbar is not aware of it. You need to manually change the scrollLeft position to 0 for the div which has overflow: scroll property which in your case is the div with slider className.

You can attach a ref to it and set scrollLeft = 0 like

class Slider extends React.Component {
  render () {
    return (
      <div ref={this.props.innerRef} className='slider'>
        {this.props.sliderContentArray.map(elementContent => <SliderElement elementContent={elementContent} />)}
      </div>
    )
  }
}

class SliderContainer extends React.Component {
  constructor () {
    super()
    this.slidersContent = [
      [1, 2, 3, 4, 5, 6, 7, 8],
      [9, 10, 11, 12, 13, 14, 15, 16]
    ]

    this.state = {
      currentSliderIndex: 0
    }
  }
  switchSlider () {
    this.setState((prevState) => {
      if (prevState.currentSliderIndex === 0) {
        return { currentSliderIndex: 1 }
      } else {
        return { currentSliderIndex: 0 }
      }
    }, () => {this.slider.scrollLeft = 0})
  }
  render () {
    return (
      <div>
        <Slider innerRef={(ref) => this.slider = ref} sliderContentArray={this.slidersContent[this.state.currentSliderIndex]} />
        <button
          className='slider-switch-button'
          onClick={this.switchSlider.bind(this)}
        >
          change slides
        </button>
      </div>
    )
  }
}

CodePen

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400