天天看點

基于react的H5開發入門基礎簡介一、react是什麼?二、元件類的定義三、元件的props(屬性)和state(狀态)四、元件的生命周期五、元件間的通信

<a href="https://facebook.github.io/react/index.html">react官方網站</a>

<a href="http://reactjs.cn/react/docs/getting-started.html">react中文文檔</a>

<a href="http://javascript.ruanyifeng.com">javascript參考教程</a>

react是一個 javascript 庫 ,可用來建立使用者界面的,可認為是mvc 中的v(視圖)。

react是 基于component 的,即元件,react認為一切頁面元素都可以抽象成元件,且大部分操作都是針對元件的。

傳統的dom(檔案對象模型)操作會對整個dom樹進行重新渲染,時間成本、複雜度高 ,很慢且容易造成卡頓使頁面短暫失去響應。

為解決dom操作慢的問題,react引入虛拟dom,比較新的與舊的虛拟dom節點之間的差異,最後将diff反映到真實dom,盡可能減少重繪,提高性能。

元件可複用性和擴充性好,開發效率提高

不直接操作dom ,先在虛拟dom中計算變化,最後将diff反應到真實的dom中,盡可能減少重繪,提高性能。

基于狀态實作對dom控制和渲染 ,是react 的一大創新,将元件看成是一個狀态機,一開始有一個初始狀态,然後使用者互動,導緻狀态變化,進而觸發重新渲染 ui。

react将新的虛拟dom(由元件的render方法傳回,也就是真實dom未來要顯示的模樣)與舊的虛拟dom(結構、資料與目前的真實dom一緻)做比較,生成差異diff,并将diff應用到目前真實的dom中,目前真實dom更新為新的真實dom(結構、資料與新的虛拟dom一緻)

在react中,開發者隻需要在元件的render方法中傳回新的虛拟dom就可以了,具體真實dom與虛拟dom如何做對比生成diff,以及真實dom如何通過最快的路徑渲染出變動的部分,均由react來完成,不用開發者操心。

基于react的H5開發入門基礎簡介一、react是什麼?二、元件類的定義三、元件的props(屬性)和state(狀态)四、元件的生命周期五、元件間的通信

元件(component)是虛拟 dom ,并不是真實的 dom 節點,而是存在于記憶體之中的一種資料結構。隻有當它插入文檔以後,才會變成真實的 dom節點,大部分情況下,我們都是在 建構react的元件,也就是操作虛拟dom ,components 的存在讓計算 dom diff 更高效。

為了同浏覽器互動,我們有時候需要擷取到 真實的dom節點 。我們可以通過調用react的react.finddomnode(component)擷取到元件中真實的dom。

react.finddomnode()隻在mounted元件中調用,mounted元件就是已經渲染在浏覽器dom結構中的元件。如果你在元件的render()方法中調用react.finddomnode()就會抛出異常,是因為 render傳回的是虛拟dom ,并沒有被渲染到真實dom中。

本文基于es6語言标準建立名為timer元件,儲存為timer.js檔案,示例代碼如下圖所示,主要包含 三個部分 :

變量聲明、引入外部依賴 -import

定義元件類 -class

元件輸出 -export

引入依賴庫/其他元件時,es6語言标準與python文法比較類似,還可以給引入的子產品取别名, 格式 為:

示例代碼中 引入外部依賴 :

常用依賴庫

react.js - react 的核心庫(常用子產品 react.component )

react-dom.js -提供與 dom 相關的功能 (常用子產品 reactdom.render 和 reactdom.finddomnode )

元件class内的函數組成結構主要包含生命周期函數、render方法以及自定義函數3部分,具體結構如下圖:

基于react的H5開發入門基礎簡介一、react是什麼?二、元件類的定義三、元件的props(屬性)和state(狀态)四、元件的生命周期五、元件間的通信

自定義元件timer(包含全部生命周期函數+render方法)的示例代碼(非完整代碼)如下:

由上圖可知 元件 :

元件可以認為是 繼承自父類react.component的一個子類

元件 擁有父類react.component的一些方法,如各種生命周期函數+render方法

元件 可定義其私有的方法 供元件内部使用

格式:方法名 (參數){函數體代碼}

元件定義時,依據元件的功能設計,生命周期函數可選擇性寫也可以不寫

若 重寫生命周期函數,被重寫的函數會覆寫掉從父類react.component繼承過來的生命周期函數

若 不重寫生命周期函數,則預設使用從父類react.component繼承過來的生命周期函數

元件的render方法主要用來傳回元件的dom結構,有如下幾個 特點 :

元件中的render方法繼承自 react.component ,是每個元件 一定要有 的,用于輸出元件。

render方法傳回的是一個 虛拟dom 節點,是一個 javascript對象 ,該對象的結構與dom節點結構類似,其傳回值可以是 null、false或react元件

render方法隻負責傳回虛拟dom來告訴react新的dom應該長什麼樣,至于虛拟dom和真實dom如何做diff,以及如何高效地将變化渲染到真實dom則由react來完成,無需程式員操作

render方法在元件 建立期 (僅一次)、 更新期 (可重複)均會被調用,且在更新期時,元件的屬性(this.props)或狀态(this.state)的變化都有可能觸發render方法的調用

此外,render方法應該是純粹的,也就是說在該方法中不修改元件state,不讀寫 dom 資訊,也不和浏覽器互動(例如使用 settimeout)。如果需與浏覽器互動,在componentdidmount() 中或者其它生命周期方法中做這件事。保持render() 純粹,可以使伺服器端渲染更加切實可行,也使元件更容易被了解。使用render方法時,需 注意 以下幾點:

render方法中 this.pops和this.state是隻讀的, 不能修改元件state

隻能傳回一個頂級元件 ,不能傳回一組元素

傳回2個頂級元素錯誤寫法

基于react的H5開發入門基礎簡介一、react是什麼?二、元件類的定義三、元件的props(屬性)和state(狀态)四、元件的生命周期五、元件間的通信

傳回兩個元素的正确寫法

基于react的H5開發入門基礎簡介一、react是什麼?二、元件類的定義三、元件的props(屬性)和state(狀态)四、元件的生命周期五、元件間的通信

render方法中 不能調用react.finddomnode() ,否則抛出異常,因為react.finddomnode()是對真實dom的操作, render方法隻是虛拟dom

<a href="https://facebook.github.io/react/docs/jsx-in-depth-zh-cn.html">jsx官方中文介紹</a>

jsx是一種特殊的js文法,可以在javascript代碼中直接使用html标簽。jsx文法是可選的,也就是說你也可以不使用,直接寫javascript原生代碼,但是建議使用,因為很友善。

若是在标簽的&lt;&gt;内,則加"";若在标簽對中間,則無需加"",例如:

要使用 javascript 表達式作為屬性值,隻需把這個表達式用一對大括号 {}包起來,不要用引号 "",其中style屬性對于jsx來說第一是變量,第二是對象,是以要兩個花括号,例如:

布爾值被認為是javascript表達式,是以需添加{},例如:

若是在标簽的&lt;&gt;内,則按javascript注釋規範即可;若是标簽對之間,需另加{},例如:

使用jsx需 注意 :

jsx 使用大、小寫的約定來區分本地元件的類和 html 标簽

某些html的屬性名是js的保留字,需重新命名(如js中classhe 和for為保留字,是以要寫成classname和htmlfor;

在js中,事件名使用駝峰命名法,比如onclick變為了onclick;

将自定義元件(timer)作為子產品輸出給外部/其他元件使用,代碼如下:

可在其他元件/外部中引入該元件并使用:

元件執行個體化(元件建立并渲染到真實的dom),需要用到reactdom.render方法:

| 差別點 | reactdom.render | 元件内的render |

| :-----------------------: | :-------------------------------: | :----------------------------:|

| 依賴庫 | react-dom.js | react.js |

| 依賴子產品 | reactdom | 繼承自react.component|

| 使用場景 | 執行個體化元件并渲染到真實dom時使用,一般頁面中最頂層元件才會使用,将所有元件一起執行個體化 | 定義任何元件時均使用 |

| 是否渲染到真實dom | 是 | 否,僅傳回虛拟dom |

react 是基于狀态實作對dom控制和渲染 ,将元件看成是一個狀态機,每一個狀态對應一個ui展現,元件狀态分為兩種:

用props(屬性)表示,用于從父元件到子元件的資料傳遞。

用state表示,元件私有,state狀态隻能在元件内部修改。

可以把props當作元件的資料源,props“屬于”父元件,隻會從父元件傳遞到子元件,是父子元件間進行狀态傳遞的接口。react中的資料流是單向的,當父元件傳遞的props改變時,react會向下周遊整個元件樹,并重新渲染使用這個props的元件。

可用setprops()方法(幾乎不用)修改元件屬性,但是隻能在元件外調用, 元件内部的this.props屬性是隻讀的,不能用于修改元件自身的屬性。

react的元件用state來表示内部狀态,可随使用者的互動而對其修改,state隻應該用于存儲簡單的視圖狀(如用于控制下拉框的可見狀态)。

state可讀可改,通過this.state通路和初始化,隻能通過setsate()方法修改,且隻能在元件内部使用,屬于元件私有。

元件的render() 方法依賴于 this.props 和 this.state ,react會確定渲染出來的 ui 界面總是與輸入( this.props 和 this.state )保持一緻。

| props、state的共同點與差別 | props | state |

| :-------------------------------: | :--------: | :--------:|

| 能否從父元件獲得初值 | yes | no |

| 是否能由父元件修改 | yes | no |

| 能否在元件内部設定預設 | yes | yes |

| 能否在元件内部修改 | no | yes |

| 是否設定子元件的初始值 | yes | no |

| 能否修改子元件的值 | yes | no |

react中一個元件就是一個狀态機,在元件的生命周期中,随着元件props或state的改變,其dom表現形式也會有所變化。元件的生命周期如下圖所示:

基于react的H5開發入門基礎簡介一、react是什麼?二、元件類的定義三、元件的props(屬性)和state(狀态)四、元件的生命周期五、元件間的通信

元件生命周期主要包括3個階段,react 為每個生命周期階段都提供了兩種處理函數,will 函數在進入狀态之前調用,did 函數在進入狀态之後調用,三種狀态共計五種處理函數。

mount(建立期):已加載到真實 dom

update(更新期):正在被重新渲染

unmount(銷毀期):已移出真實 dom

此外,react 還提供兩種特殊狀态的處理函數:

componentwillreceiveprops( nextprops):當已加載元件收到新的props時調用

shouldcomponentupdate( nextprops, nextstate):元件判斷是否重新渲染時調用

父元件timer_controller,向子元件傳遞子元件的props.content

子元件timer,包含1個button和1個p,1個props2個state

p的文本使用this.props.content

button的文本用到this.state.seconds

button的顔色用到this.state.buttoncolor

button的點選事件會改變this.state.buttoncolor

子元件timer的定時器會改變this.state.seconds,每2分鐘變化一次

基于react的H5開發入門基礎簡介一、react是什麼?二、元件類的定義三、元件的props(屬性)和state(狀态)四、元件的生命周期五、元件間的通信
基于react的H5開發入門基礎簡介一、react是什麼?二、元件類的定義三、元件的props(屬性)和state(狀态)四、元件的生命周期五、元件間的通信

用于定義子元件timer的timer.js檔案完整代碼如下:

建立期可認為是元件的執行個體化,頁面的初始化:每當元件被建立、首次渲染時,都會有一系列會被調用,調用順序、時間以及函數用途分别如下表所示,在建立期,表中函數均隻調用一次。

| 按序各調用一次 | 調用時間 | 用途 |

| :-----------------------: | :-------------------------------: | :---------------------------:|

| constructor | 構造函數,元件被建立時執行 | 可通路this.props和設定初始化state|

| componentwillmount | 元件首次渲染前調用 | 可在元件被首次render前最後一次修改state|

| render | componentwillmount執行完後| 傳回虛拟dom |

| componentdidmount |元件已在真實dom中首次渲染後調用 | 可使用reactdom.finddomnode ()擷取真實dom并操作 ,如為事件綁定監聽函數、設定定時器,發送 ajax 請求 |

基于react的H5開發入門基礎簡介一、react是什麼?二、元件類的定義三、元件的props(屬性)和state(狀态)四、元件的生命周期五、元件間的通信

操作 :首次打開頁面2分鐘内,無其他操作

效果 :頁面元件初始化,button顔色為灰,内容中的數字為1;p中的數字為9999。依次調用:

constructor (初始化this.state.seconds=0)

componentwillmount (this.state.seconds被置為1)

render

componentdidmount

基于react的H5開發入門基礎簡介一、react是什麼?二、元件類的定義三、元件的props(屬性)和state(狀态)四、元件的生命周期五、元件間的通信

當元件建立并首次渲染完成之後,元件進入更新期,當由于使用者與界面的互動或者界面元素的自更新造成元件props或state發生改變時,會有以下方法按順序根據調用條件而被觸發,這些方法除render以外均隻在更新期調用,而不會在元件初始化渲染時調用:

| 按序據條件調用 | 調用條件 | 用途 |

| ------------------------- | :-------------------------------: | --------------------------: |

| componentwillreceiveprops | 元件收到新的props時調用| 可修改state及決定是否更新props |

| shouldcomponentupdate| 接收到新的 props 或者state,将要重新渲染之前調用 | 可用于優化react渲染速度,傳回true,繼續向下執行,傳回false,停止向下執行,等待下一次props 或state發生變化 |

| componentwillupdate| shouldcomponentupdate傳回為true後調用 | 不能在此使用this.setstate()修改state |

| render |componentwillupdate之後調用 | 生成虛拟dom |

| componentdidupdate | 元件已在真實dom中重新渲染後調用 | 與componentdidmount類似,可操作真實dom |

基于react的H5開發入門基礎簡介一、react是什麼?二、元件類的定義三、元件的props(屬性)和state(狀态)四、元件的生命周期五、元件間的通信

操作 :頁面打開後2分鐘内,點選button(造成this.state.buttoncolor改變)

效果 :button顔色變紅,其他跟初始頁面一緻,依次調用:

shouldcomponentupdate (傳回true)

componentwillupdate

componentdidupdate

基于react的H5開發入門基礎簡介一、react是什麼?二、元件類的定義三、元件的props(屬性)和state(狀态)四、元件的生命周期五、元件間的通信

操作 :頁面打開後,無操作,等待2分鐘後(定時器改變this.state.seconds),第3分鐘時(父元件傳遞的this.props.content改變)

效果 :button顔色為灰,内容中的數字為2;p中的數字為9998。第2分鐘時調用的函數及順序與樣例1一緻,不同的隻是樣例2改變的是this.state.seconds,而樣例1改變的是this.state.buttonholer。第3分鐘props變化時,會依次調用:

componentwillreceiveprops

基于react的H5開發入門基礎簡介一、react是什麼?二、元件類的定義三、元件的props(屬性)和state(狀态)四、元件的生命周期五、元件間的通信

如果依然按樣例1、2一樣分别操作,隻是将shouldcomponentupdate傳回改為false,則生命周期函數停止向下執行,props、state的變化也不會重新渲染到真實dom中。

componentwillunmount:在元件從 dom 中移除的時候立刻被調用。在該方法中執行任何必要的清理,比如無效的定時器,或者清除在 componentdidmount 中建立的 dom 元素

<a href="https://segmentfault.com/a/1190000004044592">詳細介紹請點這裡或去官網檢視</a>

無父子關系的元件間通信

父元件-&gt;子元件

子元件-&gt;父元件

對于事件系統,這裡有 2 個基本操作步驟:訂閱(subscribe)/監聽(listen)一個事件通知,并發送(send)/觸發(trigger)/釋出(publish)/發送(dispatch)一個事件通知那些想要的元件。

在父元件定義回調函數,并在父元件的 render 方法中将回調函數作為子元件屬性的值傳遞給子元件。

在子元件中可通過該屬性向父元件回傳資料。

代碼示例如下:

在父元件(questionlist)中定義回調函數(handleselect),并在父元件的render方法中将handleselect作為子元件(starquestion)屬性(callbackparent)的值

在子元件中可通過this.props.callbackparent屬性向父元件回傳資料:

繼續閱讀