React Native面試題及常用知識

React Native面試題

MONDAY. MARCH 26, 2018 - 2 MINS

本文原創首發於公衆號:ReactNative開發圈,轉載需註明出處。

本文會不定期不斷更新,想查看最新版本請移步至https://github.com/forrest23/react-native-interview


1.React Native相對於原生的ios和Android有哪些優勢?

1.性能媲美原生APP 2.使用JavaScript編碼,只要學習這一種語言 3.絕大部分代碼安卓和IOS都能共用 4.組件式開發,代碼重用性很高 5.跟編寫網頁一般,修改代碼後即可自動刷新,不需要慢慢編譯,節省很多編譯等待時間 6.支持APP熱更新,更新無需重新安裝APP

缺點: 內存佔用相對較高 版本還不穩定,一直在更新,現在還沒有推出穩定的1.0版本

2.React Native組件的生命週期

生命週期 調用次數 能否使用 setSate() getDefaultProps 1(全局調用一次) 否 getInitialState 1 否 componentWillMount 1 是 render >=1 否 componentDidMount 1 是 componentWillReceiveProps >=0 是 shouldComponentUpdate >=0 否 componentWillUpdate >=0 否 componentDidUpdate >=0 否 componentWillUnmount 1 否

3.當你調用setState的時候,發生了什麼事?

當調用 setState 時,React會做的第一件事情是將傳遞給 setState 的對象合併到組件的當前狀態。 這將啓動一個稱爲和解(reconciliation)的過程。 和解(reconciliation)的最終目標是以最有效的方式,根據這個新的狀態來更新UI。 爲此,React將構建一個新的 React 元素樹(您可以將其視爲 UI 的對象表示)。 一旦有了這個樹,爲了弄清 UI 如何響應新的狀態而改變,React 會將這個新樹與上一個元素樹相比較( diff )。 通過這樣做, React 將會知道發生的確切變化,並且通過了解發生什麼變化,只需在絕對必要的情況下進行更新即可最小化 UI 的佔用空間。

4.props和state相同點和不同點

1.不管是props還是state的改變,都會引發render的重新渲染。 2.都能由自身組件的相應初始化函數設定初始值。

不同點 1.初始值來源:state的初始值來自於自身的getInitalState(constructor)函數;props來自於父組件或者自身getDefaultProps(若key相同前者可覆蓋後者)。

2.修改方式:state只能在自身組件中setState,不能由父組件修改;props只能由父組件修改,不能在自身組件修改。

3.對子組件:props是一個父組件傳遞給子組件的數據流,這個數據流可以一直傳遞到子孫組件;state代表的是一個組件內部自身的狀態,只能在自身組件中存在。

5.shouldComponentUpdate 應該做什麼

其實這個問題也是跟reconciliation有關係。 “和解( reconciliation )的最終目標是以最有效的方式,根據新的狀態更新用戶界面”。 如果我們知道我們的用戶界面(UI)的某一部分不會改變, 那麼沒有理由讓 React 很麻煩地試圖去弄清楚它是否應該渲染。 通過從 shouldComponentUpdate 返回 false, React 將假定當前組件及其所有子組件將保持與當前組件相同

6.reactJS的props.children.map函數來遍歷會收到異常提示,爲什麼?應該如何遍歷?

this.props.children 的值有三種可能: 1.當前組件沒有子節點,它就是 undefined; 2.有一個子節點,數據類型是 object ; 3.有多個子節點,數據類型就是 array 。 系統提供React.Children.map()方法安全的遍歷子節點對象

7.redux狀態管理的流程

action是用戶觸發或程序觸發的一個普通對象。 reducer是根據action操作來做出不同的數據響應,返回一個新的state。 store的最終值就是由reducer的值來確定的。(一個store是一個對象, reducer會改變store中的某些值) action -> reducer -> 新store -> 反饋到UI上有所改變。

8.加載bundle的機制

要實現RN的腳本熱更新,我們要搞明白RN是如何去加載腳本的。 在編寫業務邏輯的時候,我們會有許多個js文件,打包的時候RN會將這些個js文件打包成一個叫index.android.bundle(ios的是index.ios.bundle)的文件,所有的js代碼(包括rn源代碼、第三方庫、業務邏輯的代碼)都在這一個文件裏,啓動App時會第一時間加載bundle文件,所以腳本熱更新要做的事情就是替換掉這個bundle文件。

9.Flex佈局

採用Flex佈局的元素,稱爲Flex容器(flex Container),簡稱”容器”。它的所有子元素自動成爲容器成員,稱爲Flex項目(flex item),簡稱”項目”。 

容器默認存在兩根軸:水平的主軸(main axis)和垂直的交叉軸(cross axis)。主軸的開始位置(與邊框的交叉點)叫做main start,結束位置叫做main end;交叉軸的開始位置叫做cross start,結束位置叫做cross end。

項目默認沿主軸排列。單個項目佔據的主軸空間叫做main size,佔據的交叉軸空間叫做cross size。

容器的屬性 以下6個屬性設置在容器上。 flex-direction 屬性決定主軸的方向(即項目的排列方向)。 flex-wrap 屬性定義,如果一條軸線排不下,如何換行。 flex-flow flex-flow屬性是flex-direction屬性和flex-wrap屬性的簡寫形式。 justify-content 定義了項目在主軸上的對齊方式。 align-items 屬性定義項目在交叉軸上如何對齊。 align-content align-content屬性定義了多根軸線的對齊方式。如果項目只有一根軸線,該屬性不起作用。

10.請簡述 code push 的原理

code push 調用 react native 的打包命令,將當前環境的非 native 代碼全量打包成一個 bundle 文件,然後上傳到微軟雲服務器(Windows Azure)。 在 app 中啓動頁(或 splash 頁)編寫請求更新的代碼(請求包含了本地版本,hashCode、appToken 等信息),微軟服務端對比本地 js bundle 版本和微軟服務器的版本,如果本地版本低,就下載新的 js bundle 下來後實現更新(code push 框架實現)。

11.Redux中同步 action 與異步 action 最大的區別是什麼

同步只返回一個普通 action 對象。而異步操作中途會返回一個 promise 函數。當然在 promise 函數處理完畢後也會返回一個普通 action 對象。thunk 中間件就是判斷如果返回的是函數,則不傳導給 reducer,直到檢測到是普通 action 對象,才交由 reducer 處理。

12.React PureComponent的原理

當組件更新時,如果組件的 props 和 state 都沒發生改變, render 方法就不會觸發,省去 Virtual DOM 的生成和比對過程,達到提升性能的目的。具體就是 React 自動幫我們做了一層淺比較:

if (this._compositeType === CompositeTypes.PureClass) {
  shouldUpdate = !shallowEqual(prevProps, nextProps)
  || !shallowEqual(inst.state, nextState);
}

而 shallowEqual 又做了什麼呢?會比較 Object.keys(state | props) 的長度是否一致,每一個 key 是否兩者都有,並且是否是一個引用,也就是隻比較了第一層的值,確實很淺,所以深層的嵌套數據是對比不出來的。

13.JS調用原生方法

IOS

RCTBridgeModule RCT_EXPORT_MODULE RCT_EXPORT_METHOD RCT_REMAP_METHOD Promises Callbacks

android

ReactContextBaseJavaModule ReactMethod MyReactPackage裏增加模塊

NativeModules.MyNativeModule.callNativeMethod(‘成功調用原生方法’);

14.原生髮送事件給JS

IOS

RCTEventEmitter sendEventWithName NativeEventEmitter

android

DeviceEventEmitter.addListener

15.immutable.js 的原理

Immutable 實現的原理是 Persistent Data Structure(持久化數據結構),也就是使用舊數據創建新數據時,要保證舊數據同時可用且不變。同時爲了避免 deepCopy 把所有節點都複製一遍帶來的性能損耗,Immutable 使用了 Structural Sharing(結構共享),即如果對象樹中一個節點發生變化,只修改這個節點和受它影響的父節點,其它節點則進行共享。 Immutable 則提供了簡潔高效的判斷數據是否變化的方法,只需 === 和 is 比較就能知道是否需要執行 render(),而這個操作幾乎 0 成本,所以可以極大提高性能。修改後的 shouldComponentUpdate 是這樣的:

import { is } from 'immutable';
shouldComponentUpdate: (nextProps = {}, nextState = {}) => {
  const thisProps = this.props || {}, thisState = this.state || {};

  if (Object.keys(thisProps).length !== Object.keys(nextProps).length ||
      Object.keys(thisState).length !== Object.keys(nextState).length) {
    return true;
  }

  for (const key in nextProps) {
    if (!is(thisProps[key], nextProps[key])) {
      return true;
    }
  }

  for (const key in nextState) {
    if (thisState[key] !== nextState[key] || !is(thisState[key], nextState[key])) {
      return true;
    }
  }
  return false;
}

16.react native redux中間件

react-redux redux-actions redux-promise redux-thunk redux-logger redux-devtools

17.InteractionManager

InteractionManager可以將一些耗時較長的工作安排到所有互動或動畫完成之後再進行。這樣可以保證JavaScript動畫的流暢運行。比如 Navigator的轉場動畫。

InteractionManager.runAfterInteractions(() => {
    navigator.push({
        component: MainPager,
        name: 'MainPager'
    })
})
  componentDidMount() {
    InteractionManager.runAfterInteractions(() => {
      this.setState({renderPlaceholderOnly: false});
    });
  }

本文會不定期不斷更新,想查看最新版本請移步至https://github.com/forrest23/react-native-interview

本文題目節選自互聯網,如有侵權請聯繫我!

歡迎關注我的微信公衆號:ReactNative開發圈 

發佈了43 篇原創文章 · 獲贊 56 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章