React學習筆記(二)——React深入
2.1 事件系統
React基於Virtual DOM實現了一個SyntheticEvent層,定義的事件處理器會接收到一個SyntheticEvent物件的例項。
2.1.1 合成事件的繫結方式
React事件的繫結方式在寫法上與原生的HTML事件監聽器的屬性很相似,並且含義和觸發的場景也全都是一致的。
2.1.2 合成事件的實現機制
在React底層,主要對合成事件做了兩件事:事件委派和自動繫結。
2.1.3 在React中使用原生事件
React提供了完備的生命週期方法,其中componentDidMount會在元件已經完成安全並在瀏覽器中存在真實的DOM後呼叫,此時就可以完成原生事件的繫結。
2.1.4 合成事件與原生事件混用
雖然可以,但最好不要。
2.1.5 對比合成事件與原生事件
1.事件傳播與阻止事件傳播
瀏覽器原生DOM事件的傳播可以分為3個階段:事件捕獲階段、目標物件本身事件處理程式呼叫以及事件冒泡。
事件捕獲在程式中的意義並不大,更致命的是它的相容性問題。所以,React的合成事件並沒有實現事件捕獲,僅支援事件冒泡機制。
阻止原生事件傳播需要使用e.preventDefault,不過對於不支援該方法的瀏覽器,只能使用e.cancelBubble=true來阻止。在React合成事件中,只需要使用e.preventDefault()即可。
2.事件型別
React合成事件的事件型別是JavaScripe原生事件型別的一個子集。
3.事件繫結方式
直接在DOM元素中繫結。
在JS中,通過為元素的事件屬性賦值的方式實現繫結。
通過事件監聽函式來實現繫結。
4.事件物件
原生DOM事件物件在W3C標準和IE標準下存在著差異。在低版本的IE瀏覽器中,只能通過window.event來獲取物件。而在React合成事件系統中,不存在這種相容性問題,在事件處理函式中可以得到一個合成事件物件。
2.2 表單
2.2.1 應用表單元件
HTML表單中的所有元件在React的JSX都有相應的實現,只是它們在用法上有些區別,有些是JSX語法上的,有些則是由於React對狀態處理導致的一些區別。
2.2.2 受控元件
每當表單的狀態發生變化時,都會被寫入到元件的state中,這種元件在React中被稱為受控元件。在受控元件中,元件渲染出的狀態與它的value或checked props相對應。React通過這種方式消除了元件的區域性狀態,使得應用的整個狀態更加可控。React官方同樣推薦使用受控表單元件。
2.2.3 非受控元件
如果一個表單元件沒有value props,就可以稱為非受控元件。
2.2.4 兩者對比
最大的區別是:非受控元件的狀態並不會受應用元件的控制,應用中也多了局部元件狀態,而受控元件的值來自於元件state。
2.3 樣式處理
2.3.1 基本樣式設定
React元件最終會生成HTML,所以可以使用普通HTML設定CSS一樣的方法來設定樣式。如果想給元件新增類名,為了避免命名衝突,React中需要設定className prop。此外,也可以通過style prop來給元件設定行內樣式,注意style prop需要的是一個物件。
2.3.2 CSS Modules
CSS模組化的解決方案有很多,但主要有兩類:
InLine Style。這種方案扯淡拋棄CSS,使用JS或JSON來寫樣式,能給CSS提供JS同樣強大的模組化能力。但缺點同樣明顯,幾乎不能利用CSS本身的特性,另外,這種方案需要依賴框架實現。
CSS Modules。依舊使用CSS,但使用JS來管理樣式依賴。能最大化地結合現有CSS生態和JS模組化能力,其API非常簡潔。釋出時依舊編譯出單獨的JS和CSS檔案。
2.4 元件間通訊
2.4.1 父元件向子元件通訊
React資料流動是單向的,父元件向子元件的通訊也是最常見的方式。父元件通過props向子元件傳遞需要的資訊。
2.4.2 子元件向父元件通訊
利用回撥函式:可以拿到執行時的狀態。
利用自定義事件機制:這種方法更通用,使用也更廣泛。
在React中,子元件向父元件通訊可以使用上面的任意一種,但在這種簡單場景下利用自定義事件比較複雜,一般選擇簡單的方法。
2.4.3 跨級元件通訊
當需要讓子元件跨級訪問資訊時,可以像之前那樣向更高階元件層層傳遞props,但此時程式碼顯得不那麼優雅。在React中,還可以使用context來實現跨級父子元件間的通訊。
2.4.4 沒有巢狀關係的元件通訊
沒有巢狀關係的,那隻能通過可以影響全域性的一些機制去考慮。自定義事件機制就可以。
2.5 元件間抽象
2.5.1 mixin
1.使用理由
為創造一種類似多重繼承的效果,事實上說它是組合更為貼切。
2.封裝mixin方法
它的作用就是把任意多個源物件所擁有的自身可列舉屬性複製給目標物件,然後返回目標物件。
3.在React中使用mixin
React在使用createClass構建元件時提供了mixin屬性。
4.ES6 Classes與decorator
ES6 Classes形式構建元件時,並不支援mixin。
語法糖decorator,可以用來實現class上的mixin。
decorator是ES7中定義的新特性,與Java中的預定義註解相似。
5.mixmin的問題
破壞了原有元件的封裝。
命名衝突。
增加複雜性。
2.5.2 高階屬性
當React元件被包裹時,高階元件會返回一個增強的React元件。
2.6 元件效能優化
從React渲染過程中,防止不必要的渲染可能是最需要去解決的問題。React官方提供了一個方法,那就是PureRender。
2.6.1 純函式
純函式三大原則:
給定相同的輸入,它總是返回相同的輸出。
過程沒有副作用。
沒有額外的狀態依賴。
2.6.2 PureRender
PureRender中的Pure指的就是元件滿足純函式的條件,即元件的渲染是被相同的props和state渲染進而得到相同的結果。
2.6.3 Immutable
在傳遞資料時,可以使用Immutable Data來進一步提升元件的渲染效能。
2.6.4 key
用來標識當前項唯一性的props。