getSnapshotBeforeUpdate() 方法
1:在render之前调用,state已更新
2:典型场景:获取render之前的dom状态
我们来看一个例子,
每一秒钟都会加入一个新的<div>msg : number</div>
假如我们使用滑轮移到某个地方,内容物会随着时间不断下降,因为新生成的div会把它挤下来,如何保持不动了?
<script type = 'text/babel'>
class SnapshotSample extends React.Component {
constructor(props) {
super(props);
this.state = {
messages: [],//用于保存子div
}
}
handleMessage () {//用于增加msg
this.setState( pre => ({
messages: [`msg: ${ pre.messages.length }`, ...pre.messages],
}))
}
componentDidMount () {
for (let i = 0; i < 20; i++) this.handleMessage();//初始化20条
this.timeID = window.setInterval( () => {//设置定时器
if (this.state.messages.length > 200 ) {//大于200条,终止
window.clearInterval(this.timeID);
return ;
} else {
this.handleMessage();
}
}, 1000)
}
componentWillUnmount () {//清除定时器
window.clearInterval(this.timeID);
}
getSnapshotBeforeUpdate () {//很关键的,我们获取当前rootNode的scrollHeight,传到componentDidUpdate 的参数perScrollHeight
return this.rootNode.scrollHeight;
}
componentDidUpdate (perProps, perState, perScrollHeight) {
const curScrollTop= this.rootNode.scrollTop;
if (curScrollTop < 5) return ;
this.rootNode.scrollTop = curScrollTop + (this.rootNode.scrollHeight - perScrollHeight);
//加上增加的div高度,就相当于不动
}
render () {
return (
<div className = 'wrap' ref = { node => ( this.rootNode = node)} >
{ this.state.messages.map( msg => (
<div>{ msg } </div>
))}
</div>
);
}
}
ReactDOM.render(
<SnapshotSample />,
document.getElementById("root")
)
</script>
.wrap{
height: 100px;
width :200px;
padding: 1px solid #eee;
overflow:auto;
}
关键在于通过getSnapshotBeforeUpdate方法,获取dom信息,然后通过componentDidUpdate反映。
下面是其他方法的用途
Constructor
1: 用于初始化操作,一般很少使用
2:唯一一个直接修改state的地方,其他地方通过调用this.setState()方法。
getDerivedStateFromProps
1:当state需要从props初始化时,使用
2:尽量不使用,维护俩者状态需要消耗额外资源,增加复杂度
3:每次render都会调用
4:典型场景表单获取默认值
componentDidMount
1:UI渲染完成后调用
2:只执行一次
3:典型场景:获取外部资源
componentWillUnmount
1:组件被移除时调用
2:典型场景:资源释放
getSnapshotBeforeUpdate
1:在render之前调用,state已更新
2:典型场景:获取render之前的dom状态
componentDidUpdate
1:每次UI更新被调用
2:典型场景:页面通过props重新获取数据
shouldComponentUpdate
1:觉得Vistual Dom是否重绘
2:一般可以由PuerComponent自动实现
3:典型场景:性能优化