關於react的一些知識點總結

1、爲什麼選擇框架?

  • 組件化:使我們的工程易於維護,容易拓展

  • 分層的設計:mvvm框架等等使我們的代碼解耦易於讀寫,視圖數據分離

  • 開發效率:底層封裝好了具體的方法來更新DOM,而非我們手動操作,解放了開發者的手動DOM成本,提高開發效率。

  • 狀態管理的優化:例如vuex readux的使用

  • 現在的框架基本都有生命週期,方便我們在各個週期進行操作,比js的混雜模式更加的方便,清晰
    2、虛dom的優劣

  • 優點

  • 保證性能下限: 虛擬DOM可以經過diff找出最小差異,然後批量進行patch,這種操作雖然比不上手動優化,但是比起粗暴的DOM操作性能要好很多,因此虛擬DOM可以保證性能下限

  • 無需手動操作DOM: 虛擬DOM的diff和patch都是在一次更新中自動進行的,我們無需手動操作DOM,極大提高開發效率

  • 跨平臺: 虛擬DOM本質上是JavaScript對象,而DOM與平臺強相關,相比之下虛擬DOM可以進行更方便地跨平臺操作,例如服務器渲染、移動端開發等等

3、react的生命週期

React 16之後有三個生命週期被廢棄(但並未刪除)
componentWillMount
componentWillReceiveProps
componentWillUpdate
官方計劃在17版本完全刪除這三個函數,只保留UNSAVE_前綴的三個函數,目的是爲了向下兼容,但是對於開發者而言應該儘量避免使用他們,而是使用新增的生命週期函數替代它們
目前React 16.8 +的生命週期分爲三個階段,分別是掛載階段、更新階段、卸載階段
掛載階段:
constructor: 構造函數,最先被執行,我們通常在構造函數裏初始化state對象或者給自定義方法綁定this
getDerivedStateFromProps: static getDerivedStateFromProps(nextProps, prevState),這是個靜態方法,當我們接收到新的屬性想去修改我們state,可以使用getDerivedStateFromProps
render: render函數是純函數,只返回需要渲染的東西,不應該包含其它的業務邏輯,可以返回原生的DOM、React組件、Fragment、Portals、字符串和數字、Boolean和null等內容
componentDidMount: 組件裝載之後調用,此時我們可以獲取到DOM節點並操作,比如對canvas,svg的操作,服務器請求,訂閱都可以寫在這個裏面,但是記得在componentWillUnmount中取消訂閱
更新階段:
getDerivedStateFromProps: 此方法在更新個掛載階段都可能會調用
shouldComponentUpdate: shouldComponentUpdate(nextProps, nextState),有兩個參數nextProps和nextState,表示新的屬性和變化之後的state,返回一個布爾值,true表示會觸發重新渲染,false表示不會觸發重新渲染,默認返回true,我們通常利用此生命週期來優化React程序性能
render: 更新階段也會觸發此生命週期
getSnapshotBeforeUpdate: getSnapshotBeforeUpdate(prevProps, prevState),這個方法在render之後,componentDidUpdate之前調用,有兩個參數prevProps和prevState,表示之前的屬性和之前的state,這個函數有一個返回值,會作爲第三個參數傳給componentDidUpdate,如果你不想要返回值,可以返回null,此生命週期必須與componentDidUpdate搭配使用
componentDidUpdate: componentDidUpdate(prevProps, prevState, snapshot),該方法在getSnapshotBeforeUpdate方法之後被調用,有三個參數prevProps,prevState,snapshot,表示之前的props,之前的state,和snapshot。第三個參數是getSnapshotBeforeUpdate返回的,如果觸發某些回調函數時需要用到 DOM 元素的狀態,則將對比或計算的過程遷移至 getSnapshotBeforeUpdate,然後在 componentDidUpdate 中統一觸發回調或更新狀態。
卸載階段:
componentWillUnmount: 當我們的組件被卸載或者銷燬了就會調用,我們可以在這個函數裏去清除一些定時器,取消網絡請求,清理無效的DOM元素等垃圾清理工作

在這裏插入圖片描述
你可以參考這個網站(關於新的生命週期

4、React的請求應該放在哪個生命週期中?

React的異步請求到底應該放在哪個生命週期裏,有人認爲在componentWillMount中可以提前進行異步請求,避免白屏,其實這個觀點是有問題的.
由於JavaScript中異步事件的性質,當您啓動API調用時,瀏覽器會在此期間返回執行其他工作。當React渲染一個組件時,它不會等待componentWillMount它完成任何事情 - React繼續前進並繼續render,沒有辦法“暫停”渲染以等待數據到達。
而且在componentWillMount請求會有一系列潛在的問題,首先,在服務器渲染時,如果在 componentWillMount 裏獲取數據,fetch data會執行兩次,一次在服務端一次在客戶端,這造成了多餘的請求,其次,在React 16進行React Fiber重寫後,componentWillMount可能在一次渲染中多次調用.
目前官方推薦的異步請求是在componentDidmount中進行.
如果有特殊需求需要提前請求,也可以在特殊情況下在constructor中請求:

react 17之後componentWillMount會被廢棄,僅僅保留UNSAFE_componentWillMount

5、setstate是同步還是異步的?(合成事件和鉤子函數中是“異步”)

  1. setState只在合成事件和鉤子函數中是“異步”的,在原生事件和setTimeout 中都是同步的。
  2. setState 的“異步”並不是說內部由異步代碼實現,其實本身執行的過程和代碼都是同步的,只是合成事件和鉤子函數的調用順序在更新之前,導致在合成事件和鉤子函數中沒法立馬拿到更新後的值,形成了所謂的“異步”,當然可以通過第二個參數 setState(partialState, callback) 中的callback拿到更新後的結果。
  3. setState 的批量更新優化也是建立在“異步”(合成事件、鉤子函數)之上的,在原生事件和setTimeout 中不會批量更新,在“異步”中如果對同一個值進行多次setState,setState的批量更新策略會對其進行覆蓋,取最後一次的執行,如果是同時setState多個不同的值,在更新時會對其進行合併批量更新。

6、react組件間的通信策略

  • 父組件向子組件通訊: 父組件可以向子組件通過傳 props 的方式,向子組件進行通訊
  • 子組件向父組件通訊: props+回調的方式,父組件向子組件傳遞props進行通訊,此props爲作用域爲父組件自身的函數,子組件調用該函數,將子組件想要傳遞的信息,作爲參數,傳遞到父組件的作用域中
  • 兄弟組件通信: 找到這兩個兄弟節點共同的父節點,結合上面兩種方式由父節點轉發信息進行通信
  • 跨層級通信: Context設計目的是爲了共享那些對於一個組件樹而言是“全局”的數據,例如當前認證的用戶、主題或首選語言,對於跨越多層的全局數據通過Context通信再適合不過
  • 發佈訂閱模式: 發佈者發佈事件,訂閱者監聽事件並做出反應,我們可以通過引入event模塊進行通信
  • 全局狀態管理工具: 藉助Redux或者Mobx等全局狀態管理工具進行通信,這種工具會維護一個全局狀態中心Store,並根據不同的事件產生新的狀態

在這裏插入圖片描述
7、關於組件複用點擊https://github.com/Advanced-Interview-Question/front-end-interview/blob/master/docs/guide/abstract.md
8、對於時間分片的理解

React 在渲染(render)的時候,不會阻塞現在的線程
如果你的設備足夠快,你會感覺渲染是同步的
如果你設備非常慢,你會感覺還算是靈敏的
雖然是異步渲染,但是你將會看到完整的渲染,而不是一個組件一行行的渲染出來
同樣書寫組件的方式

時間分片正是基於可隨時打斷、重啓的Fiber架構,可打斷當前任務,優先處理緊急且重要的任務,保證頁面的流暢運行.

9、關於redux
這個是redux的過程(數據單向流動),處理異步的時候引入中間件,redux-thunk,redux-saga等等

首先,用戶(通過View)發出Action,發出方式就用到了dispatch方法。
然後,Store自動調用Reducer,並且傳入兩個參數:當前State和收到的Action,Reducer會返回新的State
State一旦有變化,Store就會調用監聽函數,來更新View。
在這裏插入圖片描述
關於react-redux

Provider: Provider的作用是從最外部封裝了整個應用,並向connect模塊傳遞store
connect: 負責連接React和Redux
(1)獲取state: connect通過context獲取Provider中的store,通過store.getState()獲取整個store tree 上所有state
(2)包裝原組件: 將state和action通過props的方式傳入到原組件內部wrapWithConnect返回一個ReactComponent對象Connect,Connect重新render外部傳入的原組件WrappedComponent,並把connect中傳入的mapStateToProps, mapDispatchToProps與組件上原有的props合併後,通過屬性的方式傳給WrappedComponent
(3)監聽store tree變化: connect緩存了store tree中state的狀態,通過當前state狀態和變更前state狀態進行比較,從而確定是否調用this.setState()方法觸發Connect及其子組件的重新渲染

在這裏插入圖片描述
10、關於它的中間件的優劣
(1)redux-chunk

redux-thunk優點:
體積小: redux-thunk的實現方式很簡單,只有不到20行代碼
使用簡單: redux-thunk沒有引入像redux-saga或者redux-observable額外的範式,上手簡單

redux-thunk缺陷:
樣板代碼過多: 與redux本身一樣,通常一個請求需要大量的代碼,而且很多都是重複性質的
耦合嚴重: 異步操作與redux的action偶合在一起,不方便管理
功能孱弱: 有一些實際開發中常用的功能需要自己進行封裝

(2)redux-saga

redux-saga優點:
異步解耦: 異步操作被被轉移到單獨 saga.js 中,不再是摻雜在 action.js 或 component.js 中
action擺脫thunk function: dispatch 的參數依然是一個純粹的 action (FSA),而不是充滿 “黑魔法” thunk function
異常處理: 受益於 generator function 的 saga 實現,代碼異常/請求失敗 都可以直接通過 try/catch 語法直接捕獲處理
功能強大: redux-saga提供了大量的Saga 輔助函數和Effect 創建器供開發者使用,開發者無須封裝或者簡單封裝即可使用
靈活: redux-saga可以將多個Saga可以串行/並行組合起來,形成一個非常實用的異步flow
易測試,提供了各種case的測試方案,包括mock task,分支覆蓋等等

redux-saga缺陷:
額外的學習成本: redux-saga不僅在使用難以理解的 generator function,而且有數十個API,學習成本遠超redux-thunk,最重要的是你的額外學習成本是隻服務於這個庫的,與redux-observable不同,redux-observable雖然也有額外學習成本但是背後是rxjs和一整套思想
體積龐大: 體積略大,代碼近2000行,min版25KB左右
功能過剩: 實際上併發控制等功能很難用到,但是我們依然需要引入這些代碼
ts支持不友好: yield無法返回TS類型

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章