概述
同時有:
1.1 創建時 的生命週期執行順序
編寫以下代碼,從而驗證constructor,render,componentDidMount的順序:
class App5 extends React.Component { constructor(props) { super(props) console.warn("生命週期鉤子函數:constructor") } componentDidMount() { console.warn("生命週期鉤子函數:componentDidMount") } render() { console.warn("生命週期鉤子函數:render") return ( <div> <h3></h3> <h1>統計豆豆被打的次數:</h1> <button id='btn'>打豆豆</button> </div> ) } } ReactDOM.render(<App5/>,document.getElementById('root9'))
在開發者工具中發現執行順序爲:
當然我們對這三個狀態還有以下總結:
備註:不能在render裏調用setstate的原因是:在render裏既能夠更新狀態,也會更新ui,具體可以參考前面的生命週期圖,render裏調用setstate,而setstate也會繼續調用render,這樣就會導致遞歸調用,從而導致error。
一定要在render裏進行調用setstate,我們可以採用箭頭函數,同時可以將this從render當中抽離出來,這樣相當於在生命週期的“更新時”再繼續更新Ui,代碼如下:
class AppThree extends React.Component { state={ count:0 } //組件當中的state,可以通過this.state來進行調用 //使用setState,來修改數據,直接使用this.state.count+1,來修改是行不通的 //備註:如果直接使用事件抽離的方法,把render函數當中的邏輯抽離出來,但是在當前class的其他 //的函數當中,是無法調用到this的。 因此在其他函數中無法調用this.setState是肯定的。 render(){ return ( <div> <h1>計數器</h1> <button onClick={() => { this.setState({ count:this.state.count+1 }) } }> +1</button> <div>這是一個有狀態組件當中的數據count。{this.state.count}</div> </div> ) } }
這樣就可以保證這裏的this不是指的render裏的this,而是render外部的this。當然還可以將這個this.setstate的邏輯進行抽離出來:
class AppSix extends React.Component { state={ count:0 } onIncrement = () => { this.setState({ count:this.state.count+1 }) } render(){ return ( <div> <h1>計數器</h1> {/*在react當中,onclick方法都需要用花括號括起來,再來表示其中的方法,這裏的箭頭函數可以直接實現調用,只是沒有對這個箭頭函數 進行命名,也就是令 hello = () => this.onIncrement(),是否命名都一樣的 */} <button onClick={this.onIncrement}>+1</button> ) } } ReactDOM.render(<AppSix />, document.getElementById('event_six'))
對於componentDidMount,我們可以在裏面進行網絡請求和dom操作,因爲它是等渲染完成後,纔開始進行這個生命進程。
1.2 更新時的生命週期
在更新時,也就是值的初始的渲染都完成了,在渲染完成後,用戶如果點擊了界面,網頁如何使用鉤子函數對不同狀態下的網頁進行檢測和更新。有三種情況都會導致組件進行重新渲染,分別是調用:
- New props(新參數被調用)
- setState()
- forceUpdate() : 也就是強制更新
class App6 extends React.Component{ constructor(props) { super(props) this.state={ count:0 } } handleClick= () => { this.setState({ count:this.state.count+1 }) } render() { return ( <div> <h3>5.2 更新時的生命週期</h3> <Counter2 count={this.state.count }/> <button onClick={this.handleClick}>打豆豆</button> </div> ) } } class Counter2 extends React.Component { render() { return <h3>統計豆豆被打的次數:{this.props.count}</h3> } } ReactDOM.render(<App6/>,document.getElementById('root10'))
這裏用到了子組件counter2,並且子組件接受到了參數props,因此在接受到了參數props後,確實會對ui進行更新,也就是進行重新渲染,我們點擊一次按鈕,子組件都會接受到一次參數,這樣打豆豆的次數就會發生變化。
我們可以看到ComponentDidUpdate()是在render函數之後,纔開始執行的,因此有以下的的圖片:
1.3 卸載時的生命週期
我們在打完豆豆超過3次後,子組件消失,因此可以使用compomentWillUnmount函數,執行清理工作。代碼如下:
class App6 extends React.Component{ constructor(props) { super(props) this.state={ count:0 } } handleClick= () => { this.setState({ count:this.state.count+1 }) } render() { return ( <div> <h3>5.2 更新時的生命週期</h3> { this.state.count > 3 ? ( <p>豆豆被打死了</p> ) :( <Counter2 count={this.state.count }/> ) } <button onClick={this.handleClick}>打豆豆</button> </div> ) } } class Counter2 extends React.Component { render() { console.warn("子組件--更新時--render函數被渲染") return <h3>統計豆豆被打的次數:{this.props.count}</h3> } componentDidUpdate() { console.warn("子組件--更新時--componentDidUpdate函數被渲染") } componentWillUnmount() { //我們在父組件當中規定了這個子組件在超過3次之後銷燬,因此銷燬後應該調用這個函數 console.warn("子組件--生命週期鉤子函數: componentWillUnmount") } } ReactDOM.render(<App6/>,document.getElementById('root10'))
我們在發現子組件消失後,確實compomentWillUnmount函數被執行了,warning被打印出。