React
学习笔记 - 生命周期(新)
生命周期(新)
生命周期的三个阶段(新) 1. 初始化阶段: 由ReactDOM.render()触发---初次渲染 1.constructor() 2.getDerivedStateFromProps(替换了旧componentWillReceiveProps)
3.render() 4.componentDidMount() 2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发 1.getDerivedStateFromProps() 2.shouldComponentUpdate() 3.render() 4.getSnapshotBeforeUpdate()
5.componentDidUpdate(preProps,preState,value) 3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发 1.componentWillUnmount()
|
案例展示
- 与上一版本的案例基本一致, 但是除去了渐变展示功能,因为如果使用渐变展示在生命周期中,每一次使用
setState
来更改透明度都会引起state
中的数据更新,这就会导致getDerivedStateFromProps
,componentDidUpdate
等生命周期运行,但是我在案例中又经常以输出来展示对应的生命周期钩子函数的运行,因此就删除了渐变展示效果!
import React, { Component } from 'react'
class Son extends Component{ state={ opacity:1, name:"lam" } render() { return ( <div> <p>-------------子组件---------------</p> <p> 父组件传过来的名字: <span style={{opacity:this.state.opacity}}> {this.props.sendName}-{this.state.name} </span> </p> </div> ) }
static getDerivedStateFromProps(nextProps, nextState){ return { name:nextProps.sendName+'生命周期加工' } }
getSnapshotBeforeUpdate(){ console.log('[更新]:getSnapshotBeforeUpdate');
return { data:'我在getSnapshotBeforeUpdate记录的数据' } }
componentDidUpdate(preProps,preState,value){ console.log('[更新]componentDidUpdate:数据更新前为(旧数据):',preState); console.log('[更新]componentDidUpdate:getSnapshotBeforeUpdate记录返回的数据为:',value); console.log('[更新]componentDidUpdate:此时数据已经更新完成'); }
componentWillUnmount(){ console.log('[卸载]componentWillUnmount:组件即将被消除,关闭定时器(渐变效果)');
} }
export default class Father extends Component { myName = React.createRef() state = { name:'lam', isShowSon:true, }
render() { console.log('[页面初始化或数据更新]:页面渲染!'); return ( <div> <p>---------------父组件---------------</p> <input ref={this.myName} id="myname"/> <button onClick={this.sendSon}>提交给子组件</button> {/* 通过标志位判断是否展示子组件 */} {this.state.isShowSon && <Son sendName={this.state.name}></Son>} <button onClick={this.death}>销毁(关闭渐变展示)</button> </div> ) }
sendSon = ()=>{ console.log('获取到父组件的输入数据',this.myName.current.value); this.setState({ name:this.myName.current.value, }) this.myName.current.value = '' }
death = ()=>{ this.setState({ isShowSon:false },()=>{ console.log('修改成功!当前子组件显示状态为:',this.state.isShowSon); }) }
static getDerivedStateFromProps(nextProps, nextState){ console.log('[初始化或数据更新]getDerivedStateFromProps,此时可以读取state或props中的最新数据:',nextState); console.log('[初始化]getDerivedStateFromProps,第一次创建组件时无法获取dom结构',document.querySelector('#myname')); return { name:'Lam' + nextState.name, } }
componentDidMount(){ console.log('[初始化]componentDidMount,此时可以获取dom结构',document.querySelector('#myname')); console.log('[初始化]componentDidMount,此时可以发送网络请求获取数据类似Vue中的Mounted'); }
shouldComponentUpdate(nextProps, nextState){
console.log('[更新]shouldComponentUpdate:数据更新的最新数据',nextState); if(this.state.name === nextState.name){ console.log('[更新]shouldComponentUpdate:最新的输入数据与原来的数据相同,页面不用重新渲染!'); return false } console.log('[更新]shouldComponentUpdate:最新的输入数据与原来的数据不同,页面需要重新渲染!'); return true } }
|
结果展示:
重要的生命周期函数
render
:初始化渲染或更新渲染调用
componentDidMount
: 开启监听, 发送网络请求等..
componentWillUnmount
: 做一些收尾工作, 如: 清理定时器
即将废弃的生命周期函数
问题所在:
componentWillMount
- 在
ssr
中 这个方法将会被多次调用, 所以会重复触发多遍,同时在这里如果绑定事件, 将无法解绑,导致内存泄漏 , 变得不够安全高效逐步废弃。
componentWillReceiveProps
- 外部组件多次频繁更新传入多次不同的
props
,会导致不必要的异步请求
componentWillUpdate
- 更新前记录
DOM
状态, 可能会做一些处理,与componentDidUpdate
相隔时间如果过长, 会导致 状态不太信
在16.8
版本后使用这些生命周期函数会出现警告,需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。
生命周期替代:
getDerivedStateFromProps(nextProps, nextState)
替代了[初始化]:componentWillMount, componentWillReceiveProps
,省略[数据更新]:componentWillUpdate
, 可认为componentWillMount
和componentWillReceiveProps
的合并,他会在组件创建以及数据更新的时候调用,类似于生命周期版本的setState
,返回一个对象会智能的覆盖掉原来的state
(属性同名覆盖,非同名则合并),但是不会引起页面的重新渲染!
getSnapshotBeforeUpdate
取代了[数据更新]:componentWillUpdate