getSnapshotBeforeUpdate()案例:每一秒list多加一条,列表的scrollTop的值动态变化达成手动拉动滚动条时,列表可视区域不再滚动
复习: scrollTop、scrollHeight
1.scrollHeight含有scroll当然这个高度与滚动相关。
读写:只读
描述:包括overflow样式属性导致的视图中不可见内容,没有垂直滚动条的情况下,scrollHeight值与元素视图填充所有内容所需要的最小值clientHeight相同。包括元素的padding,但不包括元素的margin.(整个元素滚动内容高度)
2.scrollTop
读写:可读可写
描述:这个Element.scrollTop 属性可以设置或者获取一个元素距离他容器顶部的像素距离。一个元素的 scrollTop 是可以去计算出这个元素距离它容器顶部的可见高度。当一个元素的容器没有产生垂直方向的滚动条,那它的 scrollTop 的值默认为0.(可视区域顶部距离内容顶部区域的高度 —滚动条高度)
案例的思路:
- 更新DOM时(增加list表单个数,list的scrollHeight会跟着变化)–>
- 初始化scollTop = 0 -->
- 做到手动滚动条后科室区域不变化 -->
- 将scollTop = 比之前多增高的scrollHeight值 -->
- 利用getSnapshotBeforeUpdate()去获得更新前的scrollHeight值 -->
- 在componentDidUpdate(preProps,preState,snapshot)中通过this.refs设置
相关代码:
<style>
*{
padding: 0;
margin: 0;
}
.list{
width: 200px;
height: 150px;
background-color: pink;
overflow: auto;
}
.news{
box-sizing: border-box;
border: 1px solid #1f1e1e;
height: 30px;
}
</style>
class Newlist extends React.Component{
state = {newArr:[]} //存放表单内容
//在组件挂载后 周期定时生成子表单
componentDidMount(){
setInterval(()=>{
//获取原表单
const {newArr} = this.state
//表单序号新闻模拟
const news = '新闻'+(newArr.length+1)
//更新状态
this.setState({newArr:[news,...newArr]})
},1000)
}
render(){
return(
<div className="list" ref="list">
{
this.state.newArr.map((item,index)=>{
return <div key={index} className="news">{item}</div>
})
}
</div>
)
}
//获取更新前整体高度
getSnapshotBeforeUpdate(){
return this.refs.list.scrollHeight
}
componentDidUpdate(preProps,preState,height){
console.log('------------------------------------------------------------------------');
console.log('改变前距离顶部高度',this.refs.list.scrollTop);
console.log('增加的高度',this.refs.list.scrollHeight - height);
const temp = this.refs.list.scrollTop + this.refs.list.scrollHeight - height
this.refs.list.scrollTop = Math.round(temp)
console.log('改变后距离顶部高度:',this.refs.list.scrollTop);
}
}
ReactDOM.render(<Newlist/>,document.getElementById("test"))
- 遇到的scrollTop赋值变为小数问题,目前不知道如何解决,只是简单地用了四舍五入取整做调整,若有大佬解答解答感激不尽!!!!!!!!
测试输出:
值并不是期望中的值:
总结:
重要的钩子函数:
1.render: 初始化渲染或更新渲染调用
2.componentDidMount: 开启监听,发送ajax请求
3.componentWillUnmount: 做一些收尾工作,如:清理定时器
即将废弃的钩子:
1.componentWillMount
2.componentWillReceiveProps
3.componentWillUpdate
针对的17版本react,17版本使用出现警告,下一个大版本需要加上UNSAFE_前缀才能使用,可能会被彻底废弃