之前的文章我們介紹了 React propTypes defaultProps。接下來我們將介紹 React 生命週期函式。
之前我們已經根據 create-react-app 模組建立了一個 React 專案,並定義 App.js 為根元件,即父元件,Home.js 為子元件。我們看一下兩個元件的程式碼:
App.js
1 import React, {Component} from 'react'; 2 import Home from './components/Home'; 3 4 class App extends Component { 5 constructor(props) { 6 super(props); 7 this.state = { 8 title: "我是父元件 App 的 title", 9 flag: true, 10 } 11 } 12 13 setFlag = () => { 14 this.setState({ 15 flag: !this.state.flag 16 }) 17 } 18 19 setTitle = () => { 20 this.setState({ 21 title: "我是父元件 App 更改後的 title" 22 }) 23 } 24 25 render() { 26 return ( 27 <div className="App"> 28 { 29 this.state.flag ? <Home title={this.state.title}/> : "" 30 } 31 32 <hr/> 33 {/*通過 flag 來控制子元件 Home 的掛載與銷燬*/} 34 <button onClick={this.setFlag}>控制Home元件掛載銷燬</button> 35 36 <hr/> 37 {/*通過 flag 來控制子元件 Home 的掛載與銷燬*/} 38 <button onClick={this.setTitle}>修改App元件的title值</button> 39 40 </div> 41 ); 42 } 43 } 44 45 export default App;
Home.js
1 import React, {Component} from 'react'; 2 3 class Home extends Component { 4 constructor(props) { 5 console.log('01建構函式'); 6 super(props); 7 this.state = { 8 name: '我是子元件 Home 的 name', 9 sex: 1 10 }; 11 } 12 13 //元件將要掛載的時候觸發的生命週期函式 14 componentWillMount() { 15 console.log('02元件將要掛載'); 16 } 17 18 //元件掛載完成的時候觸發的生命週期函式 19 componentDidMount() { 20 //dom操作放在這個裡面,請求資料也放在這個裡面 21 console.log('04元件掛載完成'); 22 } 23 24 //是否要更新資料 如果返回true才會執行更新資料的操作 25 shouldComponentUpdate(nextProps, nextState) { 26 console.log('01是否要更新資料'); 27 // 父元件傳遞過來的更改後的值 28 console.log(nextProps); 29 // 子元件更改後 this.state 的值 30 console.log(nextState); 31 // 如果為 true 則可以更新資料,如果為 false 則不能更新資料 32 return true; 33 } 34 35 //將要更新資料的時候觸發 36 componentWillUpdate() { 37 console.log('02元件將要更新'); 38 } 39 40 //元件更新完成 41 componentDidUpdate() { 42 console.log('04元件資料更新完成'); 43 } 44 45 //在父元件裡面改變props傳值的時候觸發的 46 componentWillReceiveProps() { 47 console.log('父子元件傳值,父元件裡面改變了props的值觸發的方法') 48 } 49 50 setName = () => { 51 this.setState({ 52 name: '我是子元件 Home 更改後的 name 值' 53 }) 54 } 55 56 //元件銷燬的時候觸發的生命週期函式,用在元件銷燬的時候執行操作 57 componentWillUnmount() { 58 console.log('元件銷燬了'); 59 } 60 61 render() { 62 console.log('03資料渲染render'); 63 return ( 64 <div> 65 {/*父元件 App 傳遞過來的 title 值*/} 66 <p>{this.props.title}</p> 67 68 <br/><br/> 69 {/*更改子元件 Home 的 name 值*/} 70 <button onClick={this.setName}>更新name的資料</button> 71 </div> 72 ); 73 } 74 } 75 76 export default Home;
我們在父元件 App 中通過 <Home /> 標籤插入子元件 Home,將 this.state 中的 title 值傳給 Home 元件,並通過一個 flag 屬性來控制該 Home 元件的掛載和銷燬,並在 App 元件中定義一個 setTitle 的方法可以改變 this.state 中 title 的值。
我們在子元件 Home 中定義了很多元件的生命週期函式,下面我們來一點點分析。
我們先來看當頁面載入時瀏覽器端的顯示:
從控制檯的輸出結果我們可以看出元件在掛在時經歷了四個階段:
1、constructor:元件在掛載前最先經歷該階段,初始化資料。
2、componentWillMount,元件將要掛載時觸發的生命週期函式。
3、render:資料渲染 render
4、componentDidMount:元件掛載完成時觸發的生命週期函式。我們可以將 DOM 操作和請求資料放在這裡面。
當我們點選 更新name的資料 的 button 按鈕時,將 this.state 中的 name 值進行更改,瀏覽器的顯示如下:
從控制檯的輸出結果我們可以看出元件在掛在時經歷了四個階段:
1、shouldComponentUpdate:是否需要更新資料,在該生命週期函式中如果 return true,則表示可以更新資料,如果 return false,則表示不允許更新資料,當更新資料時是不成功的。同時該生命週期函式中有兩個傳參 nextProps,nextState,其中 nextProps 表示父元件傳遞過來的值更改後的值,這個我們在下面的例子中解釋。nextState 表示子元件更改後子元件中 this.state 的資料,從控制檯的列印結果可以看出 this.state 中 name 值已經變成了更改後的值。
2、componentWillUpdate,將要更新資料的時候觸發的生命週期函式。
3、render:資料渲染 render
4、componentDidUpdate:元件更新完成時觸發的生命週期函式。
當我們點選 修改App元件的title值 的 button 按鈕時,該 button 是父元件 App 的的一個按鈕,將 App 元件中 this.state 的 title 值進行更改,瀏覽器的顯示如下:
從控制檯的輸出結果我們可以看出元件在掛在時經歷了五個階段:
1、shouldWillReceiveProps:在父元件裡面改變 props 傳值的時候觸發。
2、shouldComponentUpdate:是否需要更新資料,在該生命週期函式中如果 return true,則表示可以更新資料,如果 return false,則表示不允許更新資料,當更新資料時是不成功的。同時該生命週期函式中有兩個傳參 nextProps,nextState,其中 nextProps 表示父元件傳遞過來的值更改後的值,從控制檯的列印結果可以看出 App 元件 this.state 中 title 值已經變成了更改後的值。nextState 表示子元件更改後子元件中 this.state 的資料,。
3、componentWillUpdate,將要更新資料的時候觸發的生命週期函式。
4、render:資料渲染 render
5、componentDidUpdate:元件更新完成時觸發的生命週期函式。
當我們點選 控制Home元件掛載銷燬 的 button 按鈕時,該 button 是父元件 App 的的一個按鈕,當 App 元件的 this.state 中 flag 為 true 時 Home 元件掛載,當 flag 為 false 時 Home 元件銷燬,瀏覽器的顯示如下:
從控制檯的輸出結果我們可以看出元件在掛在時經歷了一個階段:
1、shouldWillUnmount:元件銷燬的時候觸發的生命週期函式。
當我們再次點選 控制Home元件掛載銷燬 的 button 按鈕時,元件又重新掛載,就會再在執行元件掛載時的生命週期函式,最後效果如下: