摘要:組件裝載過程裝載過程依次調用的生命周期函數中每個類的構造函數,創造一個組件實例,當然會調用對應的構造函數。組件需要構造函數,是為了以下目的初始化,因為生命周期中任何函數都有可能訪問,構造函數是初始化的理想場所綁定成員函數的環境。
React系列---React(一)初識React
React系列---React(二)組件的prop和state
React系列---之React(三)組件的生命周期
React嚴格定義了組件的生命周期,共3個過程:
1) 裝載過程(Mount):組件第一次在DOM樹中渲染的過程;
2) 更新過程(Update):組件被重新渲染的過程;
3) 卸載過程(Unmount):組件從DOM樹中刪除的過程。
三種不同的過程,React庫會依次調用組件的一些生命周期函數。所以,定義一個React組件,實際上就是定制這些生命周期函數。
組件裝載過程裝載過程依次調用的生命周期函數:
constructor getInitialState getDefaultProps
componentWillMount
render
componentDidMount
ES6中每個類的構造函數,創造一個組件實例,當然會調用對應的構造函數。
并不是每個組件都需要定義構造函數。后面會看到無狀態React組件是不需要定義構造函數的。
React組件需要構造函數,是為了以下目的:
1) 初始化state,因為生命周期中任何函數都有可能訪問state,構造函數是初始化state的理想場所;
2) 綁定成員函數的this環境。
這2個函數,只有在通過React.createClass方法創造的組件類才會發生作用。這是過時的方法,ES6創造的組件中用不到。
假如用React.createClass定義組件Sample,設定內部狀態foo初始值為bar,同時設定sampleProp的prop初始值為0,代碼如下:
const Sample = React.createClass({ getInitialState: function(){ return {foo: "bar"}; }, getDefaultProps: function() { return {sampleProp: 0} } });
用ES6的話,在構造函數中給this.state賦值完成狀態初始化,給類的屬性defaultProps賦值指定props初始值:
class Sample extends React.Component { constructor(props) { super(props); this.state = {foo: "bar"}; } } Sample.defaultProps = { return {sampleProp: 0}; };render
React組件可以忽略其他所有函數都不實現,但是一定要實現render函數,因為所有React組件的父類React.Component類對除render之外的生命周期函數都有默認實現。render函數并不做實際的渲染動作,它只負責返回一個JSX描述的結構,最終由React來操作渲染過程。
render函數應該是一個純函數,完全根據this.state和this.props來決定返回的結果,而且不要產生任何副作用。在render函數中去調用this.setState是錯誤的,因為一個純函數不應該引起狀態的變化。
componentWillMount和componentDidMount裝載過程中,componentWillMount和componentDidMount分別在render之前和之后調用。
不過,通常不定義componentWillMount函數,因為顧名思義,它發生在將要裝載的時候,這個時候一切都遲了,即使再調用this.setState()修改狀態也不會引發重新繪制了。換句話說,所有可以在componentWillMount中做的事情,都可以提前到constructor中去做。可以認為這個函數存在的目的就是為了和componentDidMount對稱。
而componentDidMount作用就大了。不過要注意的是,componentDidMount被調用時,前置render函數返回的東西必定已經完成了渲染,組件已經被“裝載”到DOM樹上了。
還是以ControlPanel為例,在ControlPanel中有三個Counter組件,我們修改Counter代碼,讓裝載過程的所有生命周期函數都用console.log輸出函數名和caption值,比如,componentWillMount函數如下:
componentWillMount() { console.log("enter componentWillMount " + this.props.caption); }
在瀏覽器的console里我們能看到:
enter constructor: First enter componentWillMount First enter render First enter constructor: Second enter compomentWillMount: Second enter render Second enter constructor: Third enter componentWillMount Third enter render Third enter componentDidMount First enter componentDidMount Second enter componentDidMount Third
可以清楚的看到,由于渲染需要一定的時間,所以三個組件的componentDidMount是在最后才連在一起被調用的。
componentWillMount和componentDidMount還有一個區別,就是componentWillMount可以在服務端被調用,也可以在瀏覽器端被調用;而componentDidMount只能在瀏覽器端被調用。
componentDidMount中,可通過AJAX獲取數據來填充組件內容。在componentDidMount被調用時,組件已經被裝載到DOM樹了,也可以放心的讓React和其他操縱DOM的庫(如jQuery)配合工作了。
組件更新過程當組件被裝載到DOM樹上之后,用戶在網頁上看到了第一印象,但是要提供更好的交互體驗,就要讓組件可以隨著用戶操作改變展現的內容,當props或state被修改時,就會引發組件的更新過程。
更新過程依次調用以下生命周期函數:
1) componentWillReceiveProps
2) shouldComponentUpdate
3) componentWillUpdate
4) render
5) componentDidUpdate
當組件的props發生改變時會被調用。父組件的render被調用時,被渲染的子組件也會經歷更新過程,不管父組件傳給子組件的props有沒有改變,都會觸發子組件的componentWillReceiveProps。
我們在Counter組件類里增加這個函數定義,并在console輸出一些文字:
componentWillReceiveProps(nextProps) { console.log("enter componentWillReceiveProps " + this.props.caption) }
在ControlPanel組件的render函數中,也做如下修改:
render() { console.log("enter ControlPanel render"); return (...); }
除了在ControlPanel的render函數入口增加console輸出,還增加了一個按鈕,當這個按鈕被點擊時,調用this.forceUpdate(),每個React組件都可以通過forceUpdate()強行引發一次組件重繪。
在網頁上點擊父組件新增的重繪按鈕,看到瀏覽器console輸出:
enter ControlPanel render enter componentWillReceiveProps First enter render First enter componentWillReceiveProps Second enter render Second enter componentWillReceiveProps Third enter render Third
可以看到,父組件引發重繪后,首先是父組件ControllPanel的render被調用,隨后依次3個Counter子組件的componentWillReceiveProps和render函數被調用。
然而,父組件傳給三個子組件的props值一直沒有變化,這就驗證了componentWillReceiveProps并不只是當props值變化時才被調用,父組件render時,子組件的componentWillReceiveProps也會被調用。
在網頁中,我們再嘗試點擊第一個Counter子組件的“+”按鈕,可以看到瀏覽器console輸出:
enter render First
明顯,只有第一個子組件Counter的render函數被調用,因為組件的this.setState()函數不會引發componentWillReceiveProps調用。
shouldComponentUpdate(nextProps, nextState)shouldComponentUpdate函數返回一個布爾值,告訴React庫這個組件在這次更新過程中是否要繼續。返回false會停止更新過程,就此結束,也不會引發后續的渲染了。
這個函數能夠大大提升React組件的性能,不管React的組件渲染有多快,如果發現沒有必要重新渲染,就干脆不要渲染。
修改Counter組件類增加shouldComponentUpdate函數的定義:
shouldComponentUpdate(nextProps, nextState) { return (nextProps.caption !== this.props.caption) || (nextState.count !== this.state.count); }componentWillUpdate和componentDidUpdate
如果組件的shouldComponentUpdate返回true,接下來會依次調用componentWillUpdate、render和componentDidUpdate函數。
在介紹componentDidMount函數時,說到可以利用componentDidMount函數執行其他UI代碼庫,比如jQuery代碼。那么現在,組件被更新時,也需要在componentDidUpdate函數再次調用jQuery代碼。
組件卸載過程React組件的卸載過程只涉及一個函數componentWillUnmount,這個函數適合做一些清理工作。這些清理工作往往和componentDidMount有關,比如你在componentDidMount中用非React的方法創造了一些DOM元素,如果撒手不管會造成內存泄漏,那就需要在componentWillUnmount中把這些DOM元素清理掉。
代碼:https://github.com/zhutx/reac...
React系列---React(一)初識React
React系列---React(二)組件的prop和state
React系列---之React(三)組件的生命周期
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/83673.html
摘要:用于規范的類型與必需的狀態。表示由組件更改的數據,通常是通過與用戶的交互來更改的。為了實現的修改,需要注冊事件處理程序到相應的元素上。當事件發生時,將更新后的值是從中檢索,并通知組件。通常情況下,該函數初始化狀態使用,,或其他數據存儲。 前言 上一篇文章中,我們講到了JSX的一些用法和注意事項,這次我們來講react中最基礎也是特別重要的內容:組件。這篇文章包含組件的以下內容:狀態、屬...
摘要:系列一初識系列二組件的和系列三組件的生命周期是推出的一個庫,它的口號就是用來創建用戶界面的庫,所以它只是和用戶界面打交道,可以把它看成中的視圖層。系列一初識系列二組件的和系列三組件的生命周期 React系列---React(一)初識ReactReact系列---React(二)組件的prop和stateReact系列---React(三)組件的生命周期 showImg(https://...
摘要:因為是深入系列文章,本文不會仔細介紹每個生命周期方法的使用,而是會重點講解在使用組件生命周期時,經常遇到的疑問和錯誤使用方式。父組件發生更新導致的組件更新,生命周期方法的調用情況同上所述。 文:徐超,《React進階之路》作者授權發布,轉載請注明作者及出處 React 深入系列4:組件的生命周期 React 深入系列,深入講解了React中的重點概念、特性和模式等,旨在幫助大家加深...
摘要:因為是深入系列文章,本文不會仔細介紹每個生命周期方法的使用,而是會重點講解在使用組件生命周期時,經常遇到的疑問和錯誤使用方式。父組件發生更新導致的組件更新,生命周期方法的調用情況同上所述。 React 深入系列,深入講解了React中的重點概念、特性和模式等,旨在幫助大家加深對React的理解,以及在項目中更加靈活地使用React。 組件是構建React應用的基本單位,組件需要具備數據...
摘要:給賦值也是構造函數的工作之一。在的構造函數中,還給兩個成員函數綁定了當前的執行環境,因為方式創建的組件并不自動給我們綁定到當前實例對象。我們可以利用的功能,避免判斷邏輯這種充斥在構造函數之中,讓代碼更優。 React系列---React(一)初識ReactReact系列---React(二)組件的prop和stateReact系列---React(三)組件的生命周期 組件是React...
閱讀 1122·2021-09-22 15:32
閱讀 1722·2019-08-30 15:53
閱讀 3253·2019-08-30 15:53
閱讀 1404·2019-08-30 15:43
閱讀 453·2019-08-28 18:28
閱讀 2567·2019-08-26 18:18
閱讀 669·2019-08-26 13:58
閱讀 2528·2019-08-26 12:10