React 的 16.3 版本中對生命週期進行了較大的調整,這是爲了開發者能正確地使用生命週期,避免誤解其概念而形成反模式。html
本文將重點介紹 getDerivedStateFromProps 這個生命週期。要注意的是,React 16.3 的版本中 getDerivedStateFromProps 的觸發範圍是和 16.4^ 是不一樣的,主要區別是在 setState
和 forceUpdate
時會不會觸發,具體能夠看這個生命全週期圖 。react
getDerivedStateFromProps exists for only one purpose. It enables a component to update its internal state as the result of changes in props.bash
從上邊這句話中,咱們能夠清晰知道 getDerivedStateFromProps 的做用就是爲了讓 props 能更新到組件內部 state 中。因此它可能的使用場景有兩個:函數
咱們接下來看幾個例子。ui
假設咱們有個一個表格組件,它會根據傳入的列表數據來更新視圖。spa
class Table extends React.Component {
state = {
list: []
}
static getDerivedStateFromProps (props, state) {
return {
list: props.list
}
}
render () {
.... // 展現 list
}
}
複製代碼
上面的例子就是第一種使用場景,可是無條件從 prop 中更新 state,咱們徹底不必使用這個生命週期,直接對 prop 值進行操做就行了,無需用 state 值類保存。code
在看一個例子,這個例子是一個顏色選擇器,這個組件能選擇相應的顏色並顯示,同時它能根據傳入 prop 值顯示顏色。component
Class ColorPicker extends React.Component {
state = {
color: '#000000'
}
static getDerivedStateFromProps (props, state) {
if (props.color !== state.color) {
return {
color: props.color
}
}
return null
}
... // 選擇顏色方法
render () {
.... // 顯示顏色和選擇顏色操做
}
}
複製代碼
如今咱們能夠這個顏色選擇器來選擇顏色,同時咱們能傳入一個顏色值並顯示。可是這個組件有一個 bug,若是咱們傳入一個顏色值後,再使用組件內部的選擇顏色方法,咱們會發現顏色不會變化,一直是傳入的顏色值。htm
這是使用這個生命週期的一個常見 bug。爲何會發生這個 bug 呢?在開頭有說到,在 React 16.4^ 的版本中 setState
和 forceUpdate
也會觸發這個生命週期,因此內部 state 變化後,又會走 getDerivedStateFromProps 方法,並把 state 值更新爲傳入的 prop。blog
接下里咱們來修復這個bug。
Class ColorPicker extends React.Component {
state = {
color: '#000000',
prevPropColor: ''
}
static getDerivedStateFromProps (props, state) {
if (props.color !== state.prevPropColor) {
return {
color: props.color
prevPropColor: props.color
}
}
return null
}
... // 選擇顏色方法
render () {
.... // 顯示顏色和選擇顏色操做
}
}
複製代碼
經過保存一個以前 prop 值,咱們就能夠在只有 prop 變化時纔去修改 state。這樣就解決上述的問題。
這裏小結下 getDerivedStateFromProps 方法使用的注意點:
上述的狀況在大多數狀況下都是適用,可是這邊仍是會有產生 bug 的風險。具體能夠官網提供這個例子。在 One 和 Two 的默認帳號都相同的狀況下,使用同一個輸入框組件,在切換到 Two,並不會顯示成 Two 的默認帳號。
這邊解決方法有四種:
第一種是將組件改爲徹底可控組件(也是狀態值和方法全由父類控制);
第二種是改爲徹底不可控組件(也就是組件不接受在 getDerivedStateFromProps 中經過 prop 值來改變內部狀態),而後經過設置在構造函數中把 prop 傳給 state 和設置 key 值來處理,由於 key 變化的時候 React 會從新渲染組件,而不是去更新組件。
第三種仍是保持上述組件模式,而後經過一個惟一 ID 來判斷是否更新,而不是經過 color 值來判斷。
第四種不使用 getDerivedStateFromProps,經過 ref 來把改變郵箱的方法暴露出去。
常見的反模式有兩種,上邊也有提到過。
咱們應該謹慎地使用 getDerivedStateFromProps 這個生命週期。我我的使用狀況來講,使用時要注意下面幾點:
更多詳細內容能夠閱讀官網 Blog。