getDerivedStateFromProps

新的生命週期過程

先來看看最新版本react的生命週期圖:react

getDerivedStateFromProps

React生命週期的命名一直都是很是語義化的,這個生命週期的意思就是從props中獲取state,能夠說是太簡單易懂了。bash

能夠說,這個生命週期的功能實際上就是將傳入的props映射到state上面。函數

因爲16.4的修改,這個函數會在每次re-rendering以前被調用,這意味着什麼呢?ui

意味着即便你的props沒有任何變化,而是父state發生了變化,致使子組件發生了re-render,這個生命週期函數依然會被調用。看似一個很是小的修改,卻可能會致使不少隱含的問題。this

使用

這個生命週期函數是爲了替代componentWillReceiveProps存在的,因此在你須要使用componentWillReceiveProps的時候,就能夠考慮使用getDerivedStateFromProps來進行替代了。spa

二者的參數是不相同的,而getDerivedStateFromProps是一個靜態函數,也就是這個函數不能經過this訪問到class的屬性,也並不推薦直接訪問屬性。而是應該經過參數提供的nextProps以及prevState來進行判斷,根據新傳入的props來映射到state。code

須要注意的是,若是props傳入的內容不須要影響到你的state,那麼就須要返回一個null,這個返回值是必須的,因此儘可能將其寫到函數的末尾。component

static getDerivedStateFromProps(nextProps, prevState) {
    const {type} = nextProps;
    // 當傳入的type發生變化的時候,更新state
    if (type !== prevState.type) {
        return {
            type,
        };
    }
    // 不然,對於state不進行任何操做
    return null;
}
複製代碼

getDerivedStateFromProps exists for only one purpose. It enables a component to update its internal state as the result of changes in props.cdn

從上邊這句話中,咱們能夠清晰知道 getDerivedStateFromProps 的做用就是爲了讓 props 能更新到組件內部 state 中。因此它可能的使用場景有兩個:blog

無條件的根據 prop 來更新內部 state,也就是隻要有傳入 prop 值, 就更新 state

只有 prop 值和 state 值不一樣時才更新 state 值。

咱們接下來看幾個例子。

假設咱們有個一個表格組件,它會根據傳入的列表數據來更新視圖。

class Table extends React.Component {
    state = {
        list: []
    }
    static getDerivedStateFromProps (props, state) {
        return {
            list: props.list
        }
    }
    render () {
        .... // 展現 list
    }
}


複製代碼

上面的例子就是第一種使用場景,可是無條件從 prop 中更新 state,咱們徹底不必使用這個生命週期,直接對 prop 值進行操做就行了,無需用 state 值類保存。

在看一個例子,這個例子是一個顏色選擇器,這個組件能選擇相應的顏色並顯示,同時它能根據傳入 prop 值顯示顏色。

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,若是咱們傳入一個顏色值後,再使用組件內部的選擇顏色方法,咱們會發現顏色不會變化,一直是傳入的顏色值。

這是使用這個生命週期的一個常見 bug。爲何會發生這個 bug 呢?在開頭有說到,在 React 16.4^ 的版本中 setState 和 forceUpdate 也會觸發這個生命週期,因此內部 state 變化後,又會走 getDerivedStateFromProps 方法,並把 state 值更新爲傳入的 prop。

接下里咱們來修復這個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 方法使用的注意點:

  • 在使用今生命週期時,要注意把傳入的 prop 值和以前傳入的 prop 進行比較。

  • 由於這個生命週期是靜態方法,同時要保持它是純函數,不要產生反作用。

相關文章
相關標籤/搜索