在组件重新渲染时重置滚动位置
Posted
技术标签:
【中文标题】在组件重新渲染时重置滚动位置【英文标题】:Reset scroll position on component re-render 【发布时间】:2018-04-27 01:31:23 【问题描述】:看看这支笔:https://codepen.io/segmentationfaulter/pen/XzgJyV
为方便起见,我也在此处粘贴代码。打开上面的笔后,您会看到渲染了一个滑块。向右滚动滑块,点击change slides
按钮,你会看到滑块重新渲染了不同的数字,但滑块的滚动位置没有重置。为什么滚动位置没有重置?谢谢
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>
【问题讨论】:
Scroll to the top of the page after render in react.js的可能重复 【参考方案1】:您可以针对该问题使用通用解决方案
export const history = createHistory()
history.listen((location, action) =>
window.scrollTo(0, 0)
)
有了这个监听器,你可以“观察”路由中的每一个变化
来源:https://medium.com/@nasir/reset-scroll-position-on-change-of-routes-react-a0bd23093dfe#
【讨论】:
【参考方案2】:您的滑块内容重新呈现,但滚动条不知道。对于具有overflow: scroll
属性的div
,您需要手动将scrollLeft
位置更改为0
,在您的情况下为div with slider className
。
你可以给它附加一个引用并设置scrollLeft = 0
喜欢
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
【讨论】:
【参考方案3】:每次更新组件时,您都需要使用scrollLeft 属性手动更新滚动位置。您可以在Slider
组件的componentDidUpdate
中执行此操作:
componentDidUpdate()
ReactDOM.findDOMNode(this).scrollLeft = 0;
在这里找到工作笔:https://codepen.io/danegit/pen/xPrayY?editors=0010
【讨论】:
以上是关于在组件重新渲染时重置滚动位置的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 Gatsby JS Link 组件保留滚动位置而不重置到顶部
防止多步 Formik 表单在重新渲染上一步时重置表单控件输入