一、理解
- 组件从创建到死亡它会经历一些特定的阶段。
- React组件中包含一系列勾子函数(生命周期回调函数), 会在特定的时刻调用。
- 我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作。
二、 生命周期流程图(旧)
生命周期的三个阶段(旧)
1. 初始化阶段: 由ReactDOM.render()触发---初次渲染
- constructor()
- componentWillMount() // 组件将要挂载
- render()
- componentDidMount() // 组件挂载完毕,初始化操作,开启定时器、发送网络请求、订阅消息
2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
- shouldComponentUpdate() // 控制组件更新的“阀门”
- componentWillUpdate() // 组件将要更新
- render()
- componentDidUpdate() // 组件更新完毕
3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
- componentWillUnmount() // 常做收尾工作,例如:关闭定时器、取消订阅消息
4. 组件将要接收新的props,componentWillReceiveProps
三、生命周期流程图(新17.0.1版本)
生命周期的三个阶段(新)
1. 初始化阶段: 由ReactDOM.render()触发---初次渲染
- constructor()
- getDerivedStateFromProps
- render()
- componentDidMount()
2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
- getDerivedStateFromProps // 若state的值在任何时候都取决于props,那么可以使用getDerivedStateFromProps
- shouldComponentUpdate()
- render()
- getSnapshotBeforeUpdate // 在更新之前获取快照
- componentDidUpdate()
3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
- componentWillUnmount()
四、重要的钩子
- render:初始化渲染或更新渲染调用
- componentDidMount:开启监听, 发送ajax请求
- componentWillUnmount:做一些收尾工作, 如: 清理定时器
- componentWillMount
- componentWillReceiveProps
- componentWillUpdate
五、 即将废弃的勾子
现在使用会出现警告,下一个大版本需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。
六、案例
1、新生命周期
1 <script type="text/babel"> 2 //创建组件 3 class Count extends React.Component{ 4 //构造器 5 constructor(props){ 6 console.log('Count---constructor'); 7 super(props) 8 //初始化状态 9 this.state = {count:0} 10 } 11 12 //加1按钮的回调 13 add = ()=>{ 14 //获取原状态 15 const {count} = this.state 16 //更新状态 17 this.setState({count:count+1}) 18 } 19 20 //卸载组件按钮的回调 21 death = ()=>{ 22 ReactDOM.unmountComponentAtNode(document.getElementById('test')) 23 } 24 25 //强制更新按钮的回调 26 force = ()=>{ 27 this.forceUpdate() 28 } 29 30 //若state的值在任何时候都取决于props,那么可以使用getDerivedStateFromProps 31 static getDerivedStateFromProps(props,state){ 32 console.log('getDerivedStateFromProps',props,state); 33 return null 34 } 35 36 //在更新之前获取快照 37 getSnapshotBeforeUpdate(){ 38 console.log('getSnapshotBeforeUpdate'); 39 return 'atguigu' 40 } 41 42 //组件挂载完毕的钩子 43 componentDidMount(){ 44 console.log('Count---componentDidMount'); 45 } 46 47 //组件将要卸载的钩子 48 componentWillUnmount(){ 49 console.log('Count---componentWillUnmount'); 50 } 51 52 //控制组件更新的“阀门” 53 shouldComponentUpdate(){ 54 console.log('Count---shouldComponentUpdate'); 55 return true 56 } 57 58 //组件更新完毕的钩子 59 componentDidUpdate(preProps,preState,snapshotValue){ 60 console.log('Count---componentDidUpdate',preProps,preState,snapshotValue); 61 } 62 63 render(){ 64 console.log('Count---render'); 65 const {count} = this.state 66 return( 67 <div> 68 <h2>当前求和为:{count}</h2> 69 <button onClick={this.add}>点我+1</button> 70 <button onClick={this.death}>卸载组件</button> 71 <button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button> 72 </div> 73 ) 74 } 75 } 76 77 //渲染组件 78 ReactDOM.render(<Count count={199}/>,document.getElementById('test')) 79 </script>
2、旧生命周期
1 <script type="text/babel"> 2 //创建组件 3 class Count extends React.Component{ 4 5 //构造器 6 constructor(props){ 7 console.log('Count---constructor'); 8 super(props) 9 //初始化状态 10 this.state = {count:0} 11 } 12 13 //加1按钮的回调 14 add = ()=>{ 15 //获取原状态 16 const {count} = this.state 17 //更新状态 18 this.setState({count:count+1}) 19 } 20 21 //卸载组件按钮的回调 22 death = ()=>{ 23 ReactDOM.unmountComponentAtNode(document.getElementById('test')) 24 } 25 26 //强制更新按钮的回调 27 force = ()=>{ 28 this.forceUpdate() 29 } 30 31 //组件将要挂载的钩子 32 componentWillMount(){ 33 console.log('Count---componentWillMount'); 34 } 35 36 //组件挂载完毕的钩子 37 componentDidMount(){ 38 console.log('Count---componentDidMount'); 39 } 40 41 //组件将要卸载的钩子 42 componentWillUnmount(){ 43 console.log('Count---componentWillUnmount'); 44 } 45 46 //控制组件更新的“阀门” 47 shouldComponentUpdate(){ 48 console.log('Count---shouldComponentUpdate'); 49 return true 50 } 51 52 //组件将要更新的钩子 53 componentWillUpdate(){ 54 console.log('Count---componentWillUpdate'); 55 } 56 57 //组件更新完毕的钩子 58 componentDidUpdate(){ 59 console.log('Count---componentDidUpdate'); 60 } 61 62 render(){ 63 console.log('Count---render'); 64 const {count} = this.state 65 return( 66 <div> 67 <h2>当前求和为:{count}</h2> 68 <button onClick={this.add}>点我+1</button> 69 <button onClick={this.death}>卸载组件</button> 70 <button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button> 71 </div> 72 ) 73 } 74 } 75 76 //父组件A 77 class A extends React.Component{ 78 //初始化状态 79 state = {carName:'奔驰'} 80 81 changeCar = ()=>{ 82 this.setState({carName:'奥拓'}) 83 } 84 85 render(){ 86 return( 87 <div> 88 <div>我是A组件</div> 89 <button onClick={this.changeCar}>换车</button> 90 <B carName={this.state.carName}/> 91 </div> 92 ) 93 } 94 } 95 96 //子组件B 97 class B extends React.Component{ 98 //组件将要接收新的props的钩子 99 componentWillReceiveProps(props){ 100 console.log('B---componentWillReceiveProps',props); 101 } 102 103 //控制组件更新的“阀门” 104 shouldComponentUpdate(){ 105 console.log('B---shouldComponentUpdate'); 106 return true 107 } 108 //组件将要更新的钩子 109 componentWillUpdate(){ 110 console.log('B---componentWillUpdate'); 111 } 112 113 //组件更新完毕的钩子 114 componentDidUpdate(){ 115 console.log('B---componentDidUpdate'); 116 } 117 118 render(){ 119 console.log('B---render'); 120 return( 121 <div>我是B组件,接收到的车是:{this.props.carName}</div> 122 ) 123 } 124 } 125 126 //渲染组件 127 ReactDOM.render(<Count/>,document.getElementById('test')) 128 </script>