1.4 React 元件生命週期
官方文件
1.4.1 元件
React 中元件有自己的生命週期方法,簡單理解可以為元件從 出生(例項化) -> 啟用 -> 銷燬 生命週期 hook。透過這些 hook 方法可以自定義元件的特性。 除此之外,還可以設定一些額外的規格配置。
這些生命週期方法都可以在呼叫 React。createClass 的引數物件中傳入, 我們已經使用過了一些方法:
render
getInitialState
getDefaultProps
propTypes
1.4.2 mixins
型別: array mixins
mixins 可以理解為 React 的外掛列表,透過這種模式在不同元件之間共享方法資料或者行為只需共享 mixin 就行,mixins 內定義的生命週期方法在元件的生命週期內都會被呼叫。
可能的一些疑問:
Q1。 如果元件已經定義了某個生命週期方法, mixin 內也定義了該方法,那麼 mixin 內會被呼叫還是 元件的會被呼叫?
Q2。 多個外掛都定義了相同生命週期的方法呢?
Q3。 那如果多個外掛定義了 getInitialState 這種配置方法呢,有何影響?
外掛模式並非繼承的模式,對於問題 1、2 的答案是一樣的,都會被呼叫,呼叫順序為 mixins 陣列中的順序。
A1: 都會被呼叫
A2: 都會被呼叫
A3: React 會對返回結果做智慧的合併,所有外掛的 getInitialState 都會生效,前提條件是它們返回的欄位不衝突,如果發生欄位衝突,React 會提示報錯。 同理如果是非 元件的規格方法,出於共享目的的一些方法在多個 mixin 中也不能衝突。
eg:
var
MyMixin1
=
{
componentDidMount
:
function
()
{
console
。
log
(
‘auto do something when component did mount’
);
}
};
var
MyMixin2
=
{
someMethod
:
function
()
{
console
。
log
(
‘doSomething’
);
}
};
var
MyComponnet
=
React
。
createClass
({
mixins
:
[
MyMixin1
,
MyMixin2
],
componentDidMount
:
function
()
{
// 呼叫 mixin1 共享的方法
this
。
someMethod
();
}
});
更多 mixins 的使用會在第三章中講解。
1.4.3 statics
型別: object statics
statics 可以定義元件的類方法
eg:
var MyComponent = React。createClass({
statics: {
customMethod: function(foo) {
return foo === ‘bar’;
}
}
});
MyComponent。customMethod(‘bar’); // true
React 的元件是 OOP 的思維,MyComponent 是一個 class,class 分為類方法和例項方法,例項方法可以訪問 this, 然而類方法不能,所以我們不能在 Class 中返回狀態或者屬性。
1.4.4 displayName
型別: string displayName
為了顯示除錯資訊,每個元件都會有一個名稱,JSX 在轉為 JS 的時候自動的設定 displayName, 如下:
// Input (JSX):
var
MyComponent
=
React
。
createClass
({
});
// Output (JS):
var
MyComponent
=
React
。
createClass
({
displayName
:
“MyComponent”
,
});
當然我們也可以自定義 displayName
1.4.5 生命週期方法
下圖描述了整個元件的生命週期,包含的主要幾種情況:
元件被例項化的時候
元件屬性改變的時候
元件狀態被改變的時候
元件被銷燬的時候
1.4.6 componentWillMount
void componentWillMount()
條件:
第一次渲染階段在呼叫 render 方法前會被呼叫
作用:
該方法在整個元件生命週期只會被呼叫一次,所以可以利用該方法做一些元件內部的初始化工作
1.4.7 componentDidMount
void componentDidMount()
條件:
第一次渲染成功過後,元件對應的 DOM 已經新增到頁面後呼叫
作用:
這個階段表示元件對應的 DOM 已經存在,我們可以在這個時候做一些依賴 DOM 的操作或者其他的一些如請求資料,和第三方庫整合的操作。如果嵌套了子元件,子元件會比父元件優先渲染,所以這個時候可以獲取子元件對應的 DOM。
1.4.8 componentWillReceiveProps(newProps)
void componentWillReceiveProps(
object nextProps
)
條件:
當元件獲取新屬性的時候,第一次渲染不會呼叫
用處:
這個時候可以根據新的屬性來修改元件狀態
eg:
componentWillReceiveProps: function(nextProps) {
this。setState({
likesIncreasing: nextProps。likeCount > this。props。likeCount
});
}
注意:
這個時候雖說是獲取新屬性,但並不能確定屬性一定改變了,例如一個元件被多次渲染到 DOM 中,如下面:
var Component = React。createClass({
componentWillReceiveProps: function(nextProps) {
console。log(‘componentWillReceiveProps’, nextProps。data。bar);
},
render: function() {
return
}
});
var container = document。getElementById(‘container’);
var mydata = {bar: ‘drinks’};
ReactDOM。render(
ReactDOM。render(
ReactDOM。render(
結果會輸出兩次 componentWillReceiveProps,雖然屬性資料沒有改變,但是仍然會呼叫 componentWillReceiveProps 方法。
參考 Facebook (A=>B) => (B => A)
1.4.9 shouldComponentUpdate(nextProps, nextState)
boolean shouldComponentUpdate(
object nextProps, object nextState
)
條件:
接收到新屬性或者新狀態的時候在 render 前會被呼叫(除了呼叫 forceUpdate 和初始化渲染以外)
用處:
該方法讓我們有機會決定是否重渲染元件,如果返回 false,那麼不會重渲染元件,藉此可以最佳化應用效能(在元件很多的情況)。
1.4.10 componentWillUpdate
void componentWillUpdate(
object nextProps, object nextState
)
條件:
當元件確定要更新,在 render 之前呼叫
用處:
這個時候可以確定一定會更新元件,可以執行更新前的操作
注意:
方法中不能使用 setState ,setState 的操作應該在 componentWillReceiveProps 方法中呼叫
1.4.11 componentDidUpdate
void componentDidUpdate(
object prevProps, object prevState
)
條件:
更新被應用到 DOM 之後
用處:
可以執行元件更新過後的操作
1.4.12 生命週期與單向資料流
我們知道 React 的核心模式是單向資料流,這不僅僅是對於元件級別的模式,在元件內部 的生命週期中也是應該符合單向資料的模式。資料從元件的屬性流入,再結合元件的狀態,流入生命週期方法,直到渲染結束這都應該是一個單向的過程,其間不能隨意改變元件的狀態。
1.4.13 例項練習:透過 mixin 打印出元件生命週期的執行順序
@todo