天天看點

開始學習React啦(三)

開始學習React啦(三)

一、元件生命周期

所謂的生命周期就是指某個事物從開始到結束的各個階段,當然在 React 中指的是元件從建立到銷毀的過程

在這個過程中的不同階段調用的函數,即生命周期本質就是一個函數,到了特定時機會自動執行

通過這些函數,我們可以更加精确的對元件進行控制

下面通過一張生命周期流程圖進行一個分析

開始學習React啦(三)

我們可以将生命周期分成兩個階段:

  • 挂載階段
  • 更新階段
  • 解除安裝階段

挂載階段指的是元件建立的虛拟DOM,生成真實DOM,添加到我們指定的DOM節點中

涉及到生命周期有:

  • constructor
  • static getDerivedStateFromProps(props)
  • render
  • componentDidMount

即元件對象執行個體化階段,常用于初始化資料(定義元件state與得到外部傳入的props)

注意不能在裡面使用this.setState

class App extentd App{constructor(props){this.setate = {}
    }
}複制代碼      

也不要将props資料指派給state

constructor(props) { super(props); // 不要這樣做
 this.state = { color: props.color };
}複制代碼      

如此做毫無必要(你可以直接使用 this.props.color),同時還産生了 bug(更新 prop 中的 color 時,并不會影響 state)

getDerivedStateFromProps(props)

從命名我們就得知,将傳入的props映射到state上面

如果傳入的内容不需要影響到元件的state,那麼就需要傳回一個null

class App extentd App{constructor(props){super(props)this.setate = {}
    }static getDerivedStateFromProps(nextProps, prevState) {const {type} = nextProps;// 當傳入的type發生變化的時候,更新stateif (type !== prevState.type) {return {
                type,
            };
        }// 否則,對于state不進行任何操作return null;
    }
}複制代碼      

元件挂載完成階段,這時候頁面真實DOM節點已經完成,我們可以進行一些副作用操作,如請求資料,或者擷取真實DOM結構

componentDidMount(){this.loadData()  // 異步加載資料}複制代碼      

render函數

render函數用于将VDOM生成真實DOM,是元件必須實作的方法

render(){return (<input  type="text" defaultValue={inputValue} />)
}複制代碼      

更新階段主要為元件state資料發生變化,需要重新渲染,主要有如下:

  • getDerivedStateFromProps
  • shouldComponentUpdate
  • getSnapshotBeforeUpdate
  • componentDidUpdate

這裡主要講述getSnapshotBeforeUpdate、componentDidUpdate這兩個生命周期

該生命周期代替componentWillUpdate

特點

  • 讀取到的 DOM 元素狀态是可以保證與 componentDidUpdate 中一緻的
  • 傳回的任何值都将作為參數傳遞給componentDidUpdate
getSnapshotBeforeUpdate(){return {foo:'foo'}
}componentDidUpdate(prevProps, prevState,a){console.log(a)  // {foo:'foo'}}複制代碼      

可以拿到更新前的props和state,并且第三個參數能拿到getSnapshotBeforeUpdate傳回的值

元件已經挂載完成,這時候state與DOM都是最新的

componentDidUpdate(prevProps, prevState,snapshot){console.log(snapshot)  // {foo:'foo'}}複制代碼      

不要直接componentDidUpdate中調用this.setState,應該在判斷語句if當中,否則會造成無限更新情況

componentDidUpdate(prevProps, prevState,snapshot){console.log(snapshot)  // {foo:'foo'}}複制代碼      

二、受控元件與非受控元件

一句話講,受控元件指的是将元件的内部狀态與state保持一緻

<input type"text" value={inputValue}/>複制代碼      

這時候在标簽内輸入值,我們會發現input标簽的值并不會顯示,原因是value值已經時刻被inputValue賦予了,inputValue值并沒有發生變化

<input
    type="text"value={inputValue}
    onChange={({ target }) => {this.setState({inputValue: target.value
        })
    }} />複制代碼      
<input  type="text" defaultValue={inputValue} />複制代碼      

繼續閱讀