一、理解
- 組件從創建到死亡它會經歷一些特定的階段。
- 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>