1、prop和statereact
一、易於維護組件的設計要素瀏覽器
(1)高內聚:把邏輯緊密的相關內容放在一個組件中服務器
(2)低耦合:不一樣組件之間的依賴關係儘可能弱化函數
二、React組件的數據
測試
分兩種(都會引起組件的從新渲染):ui
prop:組件對外接口;(通常用在組件之間傳參)this
state:組件內部狀態;(通常用在組件內部初始化)spa
三、React的prop:組件的prop很像是HTML元素的屬性,可是HTML元素的屬性值都是字符串,而React組件的prop所支持的類型幾乎包含人一JS中所支持的類型設計
注意:3d
<SampleButton id=」 sample」 borderWidth={2} onClick={onButtonClick} style={{color: 」 red」}} />
style值中的{{}} , 外層表示JSX語法,內層表示對象
(1)賦值
引入主入口組件App(另外一個組件是第一章的demo)
向三個ControlPanel的子組件Counter進行賦值,使用了caption和initValue兩個prop
(2)讀取prop值
經過props 進行 讀取值
結果顯示:
(3)propType進行prop接口規範
此時對prop值進行了約束,
對caption必須是string,而且isRequired表示caption爲必填值
對initValue必須爲number
若是不按約束標準進行,如
則報錯
注意:
即便在上面 propTypes 檢查出錯的狀況下,組件依舊能工做 。 也就是說 propTypes檢查只是一個輔助開發的功能,並不會改變組件的行爲。
四、React的state:幫助記錄組件自身的數據變化
注意:組件的state必須是JS對象,不能是其餘數據類型
(1)初始化值
能夠換一種更優雅的寫法
同樣能夠實現默認值爲0的效果
(2)讀取和更新state
若是不使用setState(),修改代碼以下
此時點擊「+」,則會彈出警告
注意:
在不使用setState()狀況下,當連續點擊10次「+」,數值並無發生改變
而後再次點擊「-」時,數值直接變成9
能夠看出在咱們連續點擊「+」,其實state值已經開始進行累加,可是沒有渲染到頁面上,當咱們點擊「-」時,使用setState(),將減去1以後的結果9顯示在頁面上
總結:直接使用state修改值,只修改了內部狀態,並無引發從新渲染
五、prop和state的對比
(1)prop定義外部接口,state記錄內部狀態
(2)prop的賦值在組件外部,state的賦值在組件內部
(3)組件不該該改變prop的值,而state的值容許被修改
(
組件不該該改變prop的值的緣由:
假設一個場景,父組件包含多個子組件,而後將一個JS對象做爲prop值傳給這幾個子組件,而某個子組件修改了這個對象的內部值,
那麼其餘子組件在讀取那個對象的值時都會受到影響,致使程序混亂
書上沒有實踐案例,本身寫個小demo測試一下(將以前代碼都放demo1了,這次新建立demo2),以下:
首先,將父組件引入主入口文件
在Parent組件中,初始化content對象,並將它做爲prop值,分別傳入兩個子組件
ChildOne組件對prop值進行直接修改,ChildTwo組件中對prop值進行顯示,觀察prop值是否變化
結果:
先點擊ChildOne,而後點進ChilTwo進行顯示,發現prop值在子組件Children發生改變,丟失了最初的值
)
2、組件的生命週期(v16.6.0)
截取react官網生命週期圖
(1)裝載過程(Mount):組件第一次在DOM樹中渲染過程;
(2)更新過程(Update):當組件被從新渲染過程;
(3)卸載過程(Unmount):組件從DOM中刪除的過程;
一、裝載過程的對應函數:
(1)constructor:當建立組件類的實例時,會調用對應構造函數
注意:無狀態的React組件,不須要定義構造函數
React組件定義構造函數的目的:
(i)初始化state
(ii)綁定成員函數的this環境
注意:
在ES6語法下,類的每一個成員函數在執行時的this並非和類實例自動綁定的,而在構造函數中,this就是當前組件的實例。
因此,爲了方便未來的調用,在構造函數中將這個實例的特定函數綁定this爲當前實例。
如:
this .onClickincrementButton = this .onClickincrementButton.bind(this);
(2)render:React組件中最重要的函數,一個React組件能夠不實現其餘全部函數,可是必定要實現render函數
(i)某些特殊組件不是用來渲染界面,就讓render函數返回一個null或者false,等於告訴React,這個組件不須要渲染DOM元素
(ii)render函數是一個純函數,根據this.state和this.props決定返回結果,不能在裏面進行this.setState改變狀態
(3)componentWillMount和componentDidMount:
(i)componentWillMount:這個函數在渲染前被調用,幾乎不會被使用到,由於全部能夠在這個 componentWillMount 中作的事情,均可以提早到 constructor 中間去作
(ii)componentDidMount:這個函數被調用時,組件已經被裝載到DOM樹上了
注意:
![]()
執行順序,結果:
能夠看出componentWillMount緊貼着本身組件的render函數以前被調用,componentDidMount在三個組件的render函數都被調用以後,
三個組件的componentDidMount才連着被一塊兒調用。
緣由:
是由於 render 函數自己並不往 DOM 樹上渲染或者裝載內容,它只是返回一個 JSX表示的對象,而後由 React庫來根據返回對象決定如何渲染。而 React庫確定是要把全部組件返回的結果綜合起來,才能知道該如何產生對應的 DOM修改。 因此,只有 React庫調用三個 Counter組件的 render函數以後,纔有可能完成裝載,這時候纔會依次調用各個組件的 componentDidMount 函數做爲裝載過程的收尾 。
(iii)componentWillMount能夠在服務器端或瀏覽器端被調用,componentDidMount只能在瀏覽器端被調用
(iv)在 componentDidMount 被調用的時候,組件已經被裝載到 DOM 樹上了,能夠配合其餘的第三方UI庫(如:jQuery),進行添加新的功能
二、更新過程的對應函數:
(1)componentWillReceiveProps(nextProps)
(i)經過 this.setState方法觸發的更新過程不會調用這個函數;
(ii)只要是父組件的render函數被調用,在render函數裏面被渲染的子組件就會經歷更新過程,
無論父組件傳給子組件的props有沒有改變,都會觸發子組件的componentWillReceiveProps函數
根據以下例子證實:
父組件
當觸發onClick事件時,引起一個匿名函數,經過forceUpdate進行從新繪製(每一個React組件均可以經過forceUpdate函數強行進行從新繪製)
子組件
運行結果
顯示頁面初始化的數據,當進行點擊Click me to repaint!時
此時能夠看出:
執行次序是當父組件的render被調用後,引起了子組件中componentWillReceiveProps的調用,最後子組件中的render也被調用了;
再次渲染子組件時,它們的props並無變化,可是子組件中componentWillReceiveProps依然被調用了 (有須要在子組件對nextProps和this.props值進行比較)
再驗證一下this.setState能不能觸發componentWillReceiveProps
此時能夠看出:
當前組件調用this.setState函數,不會引起componentWillReceiveProps函數
(2)shouldComponentUpdate(nextProps,nexState):除了render以外最重要的函數,經過返回的布爾值決定何時組件不須要渲染,
(i)若是咱們要定義 shouldComponentUpdate,那就根據這兩個參數,外加 this.props和 this.state來判斷是返回true,仍是false,來避免重複渲染
(ii)經過this.setState函數引起更新過程,並非馬上更新組件的state值,在執行到函數shouldComponentUpdate的時候,this.state依然是this.setState函數執行以前的值
如:
運行結果:
能夠看出,三個Counter組件的render函數沒有被調用,由於這個刷新沒有改變caption值或count,減小了沒必要要的渲染
(3)componentWillUpdate和componentDidUpdate
(i) componentDidUpdate函數,不只在瀏覽器端能夠執行,服務器端也能夠執行
(ii)在配合其餘第三方UI庫時(如:jQuery),當React組件被更新時,原有內容會被從新繪製,這時候須要在componentDidUpdate函數再次調用jQuery代碼
三、卸載過程的對應函數:
(1)componentWillUnmount:當React組件要從DOM樹上刪除以前,此函數會被調用,適合作一些清除工做(如:防止內存泄漏)
3、組件向外傳遞數據
經過onUpdate這個prop值爲onCounterUpdate函數,做爲「橋樑」,經過函數的參數進行「溝通」