系列文章目录
👏欢迎来到我的React系列文章
🍭本系列文章从React入门开始,涵盖了React的一切基础,属于是从零开始的一个系列
🍭文章会以图文结合-动图-代码实现-解释代码的形式带领大家走进React的世界
🍭本系列会从React v16.8 开始 => 直到React v 18.0 新版旧版一起抓
🍭持续更新中~希望大家能够喜欢,系列文章👉点这里
🌈博客主页👉点这里
👋回见~
- 🔥React入门与概览(JSX语法)
- 🔥面向组件编程——组件实例的三大核心属性state、props和refs超详解
- 🔥受控组件与非受控组件(vue和react的双向绑定分别是怎么实现的?)
- 🔥React函数的柯里化(什么?这玩意儿不仅能装x,还能优化代码?)
- 🔥四行代码让我的cpu跑上90度——走进组件生命周期
- 🔥图文详解react组件生命周期——React v16.8
- 🔥react新生命周期图文详解——最新版
- 🔥react-getSnapshotBeforeUpdate()生命周期函数详解
文章目录
前言
本篇文章主要讲解新生命周期中的getSnapshotBeforeUpdate钩子🪝,全套生命周期请移步👉这里
🥤介绍getSnapshotBeforeUpdate(可以点我哟)
理解:
// 在组件更新之前获取快照,但此用法并不常见getSnapshotBeforeUpdate(prevProps, prevState){
console.log('Count-getSnapshotBeforeUpdate')returnnull}
这个用法并不是常见,但这个新钩子🪝比上一个新钩子更有意义,比如你可以在需要刷新保持滚动位置时可以使用这个钩子🪝。
需要注意的是:这个钩子必须有返回值(但是它是放在组件实例对象上的),返回值要么是
null
,要么是
snapshot value
。
什么是
snapshot value
呢?也就是一切你希望在组件更新前保留的值,比如表格的高度、滚动条的位置等等…你可以把它想象成组件的
日志备份
。
而官方文档中也明确说明了:
此生命周期的任何返回值将作为参数传递给
componentDidUpdate()
生命周期函数:
// 组件更新完毕的钩子componentDidUpdate(prevProps, prevState, snapshotValue){
console.log('Count-componentDidUpdate', snapshotValue)}
我们可以在
componentDidUpdate
中接受到这个返回值(第三个参数)。
🍓详解getSnapshotBeforeUpdate
我们要实现这样的一个示例:(处理滚动线程)
需求:
- 实现弹幕自动刷新,1s刷新一条弹幕并展示在最上方;
- 鼠标控制滚动条滚动到某一位置,界面不动,不会自动跳转到最顶部新出现的弹幕上去;
- 这个需求类似直播弹幕,用户滚动到之前的弹幕停留下来阅读,界面不会随着新出现的弹幕而变换跳转到新出现的弹幕上去。
🍰代码实现
css:
<style>
.list{width: 200px;height: 150px;background-color: skyblue;/* 放不下的新闻会出现滚动条 */overflow: auto;}.news{height: 30px;}
</style>
jsx:
<script type="text/babel">classNewsListextendsReact.Component{
state ={newsArr:[]}componentDidMount(){setInterval(()=>{// 获取原状态const{ newsArr }=this.state
// 模拟一条新闻const news ='弹幕'+(newsArr.length +1)// 更新状态this.setState({newsArr:[news,...newsArr]});// news表示现在的,...newsArr表示之前的},1000)}getSnapshotBeforeUpdate(prevProps, prevState){returnthis.refs.list.scrollHeight
}componentDidUpdate(prevProps, prevState, snapshotValue){// 现在的高度减去之前的高度this.refs.list.scrollHeight - snapshotValuethis.refs.list.scrollTop +=this.refs.list.scrollHeight - snapshotValue
// this.refs.list.scrollTop = // this.refs.list.scrollTop + this.refs.list.scrollHeight - snapshotValue}render(){return(<div className="list" ref="list">{this.state.newsArr.map((news, index)=>{return<div className="news" key={index}>{news}</div>})}</div>);}}
ReactDOM.render(<NewsList />, document.getElementById('test'))</script>
🍰代码解释
css:存放弹幕的盒子高度为150px,每条弹幕高度为30px;
jsx:
初始化状态,将弹幕初始化为空数组
state ={newsArr:[]}
组件挂载完毕后调用componentDidMount设置计时器,实现弹幕1s出现一条
componentDidMount(){setInterval(()=>{// 获取原状态const{ newsArr }=this.state
// 模拟一条新闻const news ='弹幕'+(newsArr.length +1)// 更新状态this.setState({newsArr:[news,...newsArr]});// news表示现在的,...newsArr表示之前的},1000)}
调用render,渲染组件到页面
render(){return(<div className="list" ref="list">{this.state.newsArr.map((news, index)=>{return<div className="news" key={index}>{news}</div>})}</div>);}
调用
g
e
t
S
n
a
p
s
h
o
t
B
e
f
o
r
e
U
p
d
a
t
e
getSnapshotBeforeUpdate
getSnapshotBeforeUpdate,获取组件更新前的弹幕列表内容高度
getSnapshotBeforeUpdate(prevProps, prevState){returnthis.refs.list.scrollHeight
// return 返回的内容高度传给了componentDidUpdate作为第三个参数}
调用componentDidUpdate,拿到第三个参数(getSnapshotBeforeUpdate的返回值),用更新后的高度减去更新前的高度得出新弹幕的高度(30px),再赋值给scrollTop,隐藏的高度就是新出现的弹幕的高度,每隔1s新出现一条弹幕即被隐藏,实现需求。
componentDidUpdate(prevProps, prevState, snapshotValue){// 现在的高度减去之前的高度this.refs.list.scrollHeight - snapshotValuethis.refs.list.scrollTop +=this.refs.list.scrollHeight - snapshotValue
// this.refs.list.scrollTop = this.refs.list.scrollTop + this.refs.list.scrollHeight - snapshotValue}
⬇️总结
生命周期函数getSnapshotBeforeUpdate的返回值传入componentDidUpdate作为第三个参数,可以在组件更新之前拿到之前组件的各种数据、状态和参数(拿到什么取决于自己返回什么),在该例中拿到组件更新之前内容的高度,再用组件更新之后内容的高度减去之前的高度得出新刷新出来的弹幕的高度是多少,隐藏这部分高度即可让页面保持位置不变,完成需求。
好啦~今天的文章就先到这里啦,如果在文章中发现错误还请各位道友私信我以便更改~
原创不易,如果对你有帮助的话,请不要吝啬你的三连哟✅~
感谢各位道友的支持✅回见~
版权归原作者 codeMak1r. 所有, 如有侵权,请联系我们删除。