前端面試寶典之react篇
React 中 keys 的作用是什麼?
Keys 是 React 用於追蹤哪些列表中元素被修改、被新增或者被移除的輔助標識
-
在開發過程中,我們需要保證某個元素的 key 在其同級元素中具有唯一性。在 React Diff 演算法中 React 會藉助元素的 Key 值來判斷該元素是新近建立的還是被移動而來的元素,從而減少不必要的元素重渲染。此外,React 還需要藉助 Key 值來判斷元素與本地狀態的關聯關係,因此我們絕不可忽視轉換函式中 Key 的重要性
傳入 setState 函式的第二個引數的作用是什麼?
該函式會在setState函式呼叫完成並且元件開始重渲染的時候被呼叫,我們可以用該函式來監聽渲染是否完成:
this.setState(
{ username: 'tylermcginnis33' },
() => console.log('setState has finished and the component has re-rendered.')
)
this.setState((prevState, props) => {
return {
streak: prevState.streak + props.count
}
})
React 中 refs 的作用是什麼
-
Refs 是 React 提供給我們的安全訪問 DOM 元素或者某個元件例項的控制代碼
-
可以為元素新增ref屬性然後在回撥函式中接受該元素在 DOM 樹中的控制代碼,該值會作為回撥函式的第一個引數返回
在生命週期中的哪一步你應該發起 AJAX 請求
我們應當將AJAX 請求放到 componentDidMount
函式中執行,主要原因有下
-
React 下一代調和演算法 Fiber 會通過開始或停止渲染的方式優化應用效能,其會影響到 componentWillMount 的觸發次數。對於 componentWillMount 這個生命週期函式的呼叫次數會變得不確定,React 可能會多次頻繁呼叫 componentWillMount。如果我們將 AJAX 請求放到 componentWillMount 函式中,那麼顯而易見其會被觸發多次,自然也就不是好的選擇。
-
如果我們將 AJAX 請求放置在生命週期的其他函式中,我們並不能保證請求僅在元件掛載完畢後才會要求響應。如果我們的資料請求在元件掛載之前就完成,並且呼叫了setState函式將資料新增到元件狀態中,對於未掛載的元件則會報錯。而在 componentDidMount 函式中進行 AJAX 請求則能有效避免這個問題
shouldComponentUpdate 的作用
shouldComponentUpdate 允許我們手動地判斷是否要進行元件更新,根據元件的應用場景設定函式的合理返回值能夠幫我們避免不必要的更新
如何告訴 React 它應該編譯生產環境版
通常情況下我們會使用 Webpack 的 DefinePlugin 方法來將 NODE_ENV 變數值設定為 production。編譯版本中 React 會忽略 propType 驗證以及其他的告警資訊,同時還會降低程式碼庫的大小,React 使用了 Uglify 外掛來移除生產環境下不必要的註釋等資訊
概述下 React 中的事件處理邏輯
為了解決跨瀏覽器相容性問題,React 會將瀏覽器原生事件(Browser Native Event)封裝為合成事件(SyntheticEvent)傳入設定的事件處理器中。這裡的合成事件提供了與原生事件相同的介面,不過它們遮蔽了底層瀏覽器的細節差異,保證了行為的一致性。另外有意思的是,React 並沒有直接將事件附著到子元素上,而是以單一事件監聽器的方式將所有的事件傳送到頂層進行處理。這樣 React 在更新 DOM 的時候就不需要考慮如何去處理附著在 DOM 上的事件監聽器,最終達到優化效能的目的
createElement 與 cloneElement 的區別是什麼
createElement 函式是 JSX 編譯之後使用的建立 React Element 的函式,而 cloneElement 則是用於複製某個元素並傳入新的 Props
redux中介軟體
中介軟體提供第三方外掛的模式,自定義攔截 action -> reducer 的過程。變為 action -> middlewares -> reducer 。這種機制可以讓我們改變資料流,實現如非同步 action ,action 過濾,日誌輸出,異常報告等功能
-
redux-logger:提供日誌輸出
-
redux-thunk:處理非同步操作
-
redux-promise:處理非同步操作,actionCreator的返回值是promise
redux有什麼缺點
-
一個元件所需要的資料,必須由父元件傳過來,而不能像flux中直接從store取。
-
當一個元件相關資料更新時,即使父元件不需要用到這個元件,父元件還是會重新render,可能會有效率影響,或者需要寫複雜的shouldComponentUpdate進行判斷。
react元件的劃分業務元件技術元件?
-
根據元件的職責通常把元件分為UI元件和容器元件。
-
UI 元件負責 UI 的呈現,容器元件負責管理資料和邏輯。
-
兩者通過React-Redux 提供connect方法聯絡起來
react生命週期函式
蒼青浪 關於React面試題彙總 1、redux中介軟體
中介軟體提供第三方外掛的模式,自定義攔截 action -> reducer 的過程。變為 action -> middlewares -> reducer 。這種機制可以讓我們改變資料流,實現如非同步 action ,action 過濾,日誌輸出,異常報告等功能。
常見的中介軟體:
redux-logger:提供日誌輸出
redux-thunk:處理非同步操作
redux-promise:處理非同步操作,actionCreator的返回值是promise
2、redux有什麼缺點
1.一個元件所需要的資料,必須由父元件傳過來,而不能像flux中直接從store取。
2.當一個元件相關資料更新時,即使父元件不需要用到這個元件,父元件還是會重新render,可能會有效率影響,或者需要寫複雜的shouldComponentUpdate進行判斷。
3、react元件的劃分業務元件技術元件?
根據元件的職責通常把元件分為UI元件和容器元件。
UI 元件負責 UI 的呈現,容器元件負責管理資料和邏輯。
兩者通過React-Redux 提供connect方法聯絡起來。
具體使用可以參照如下連結:http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_three_react-redux.html
react生命週期函式
初始化階段
-
getDefaultProps:獲取例項的預設屬性
-
getInitialState:獲取每個例項的初始化狀態
-
componentWillMount:元件即將被裝載、渲染到頁面上
-
render:元件在這裡生成虛擬的DOM節點
-
omponentDidMount:元件真正在被裝載之後
執行中狀態
-
componentWillReceiveProps:元件將要接收到屬性的時候呼叫
-
shouldComponentUpdate:元件接受到新屬性或者新狀態的時候(可以返回false,接收資料後不更新,阻止render呼叫,後面的函式不會被繼續執行了)
-
componentWillUpdate:元件即將更新不能修改屬性和狀態
-
render:元件重新描繪
-
componentDidUpdate:元件已經更新
銷燬階段
-
componentWillUnmount:元件即將銷燬
react效能優化是哪個周期函式
shouldComponentUpdate 這個方法用來判斷是否需要呼叫render方法重新描繪dom。因為dom的描繪非常消耗效能,如果我們能在shouldComponentUpdate方法中能夠寫出更優化的dom diff演算法,可以極大的提高效能
為什麼虛擬dom會提高效能
虛擬dom相當於在js和真實dom中間加了一個快取,利用dom diff演算法避免了沒有必要的dom操作,從而提高效能
具體實現步驟如下
-
用 JavaScript 物件結構表示 DOM 樹的結構;然後用這個樹構建一個真正的 DOM 樹,插到文件當中
-
當狀態變更的時候,重新構造一棵新的物件樹。然後用新的樹和舊的樹進行比較,記錄兩棵樹差異
-
把2所記錄的差異應用到步驟1所構建的真正的DOM樹上,檢視就更新
diff演算法?
-
把樹形結構按照層級分解,只比較同級元素。
-
給列表結構的每個單元新增唯一的key屬性,方便比較。
-
React 只會匹配相同 class 的 component(這裡面的class指的是元件的名字)
-
合併操作,呼叫 component 的 setState 方法的時候, React 將其標記為 - dirty.到每一個事件迴圈結束, React 檢查所有標記 dirty 的 component 重新繪製.
-
選擇性子樹渲染。開發人員可以重寫shouldComponentUpdate提高diff的效能
react效能優化方案
-
重寫shouldComponentUpdate來避免不必要的dom操作
-
使用 production 版本的react.js
-
使用key來幫助React識別列表中所有子元件的最小變化