React Native 0.59.x新特性解讀

xiangzhihong發表於2019-04-17

概述

眾所周知,在現在的前端技術開發棧中,跨平臺開發是一個重要的課題,不管是老牌的Hybird還是最近流行的RN、Weex還是Flutter,不得不說,現在前端和客戶端的界限越來越模糊。

最近在寫《React Native跨平臺開發進階》一書,也是對之前的《React Native移動跨平臺開發實戰》的升級(ps,由於之前的寫作功底較淺,所以寫的並不是很好)。最近,RN釋出了 0.59.x 系列版本,可以發現上層設計出現了比較大的調整,經過體驗之後,就想聊聊RN新版本的升級體驗和新特性。

相信從事移動開發的同學都清楚,最近兩三年來,跨平臺開發的技術可以說是越來越盛行,前端和客戶端的界限也越來越模糊。我對RN的認識是2016年攜程的一次技術分享,當時只是覺得使用js來寫客戶端很快,雖然當時的效能並不是很好,抱著擁抱新技術的態度,我在跨平臺的方向上也越走越遠、越走越深。

曾經,Aribnb 的 “為什麼 Airbnb 放棄了 React Native” 讓我一度懷疑RN是不是要涼涼了,不過好在Facebook 並沒有放棄 RN,甚至官宣《Facebook 正在重構 React Native,將重寫大量底層》 ,雖然重構後的RN還沒有對外發布,但是可以遇見,重構後的RN將變得越來越好。

最近,Facebook更新了最新版本0.59.4,新版本主要更新了以下新特性: 1、減輕了 React-Native 自身框架,將 webView 、viewPager、netinfo、async-storage 等內建包拆分,通過社群獨立維護,並逐步模糊 React 和 React-Native 的界限。 2、更新 JavaScriptCore 、upgrade 和 CLI 工具。 3、支援 React Hooks 。 4、修復了 FlatList 等列表控制元件中的諸多問題。

按照這一趨勢,未來React Native還將在以下方便加大力度: 1、減輕 JSBridge 的依賴。 2、通過 Fabric UI架構,將 Shadow 層、 UIManager 、NativeModule 從 Java 移到 C++ 中,從而支援 雙向的同步和非同步渲染與呼叫 。

關於這方面的精簡的知識,大家可以參考京東的 《庖丁解牛!深入剖析 React Native 下一代架構重構》和攜程的 《攜程開源RN開發框架CRN》

新特性

在0.59.0版本釋出以來,RN最近都在經歷小版本的迭代,最近的版本為0.59.4。在0.59.x版本中主要有一些新的功能和特性:

React Hooks

React Hooks 是此版本的一部分,它允許跨元件重用有狀態邏輯。Hooks的內容可以參考下面的內容: Introducing Hooks:解釋了為什麼在 React 新增 Hook。 Hooks at a Glance:對內建 Hooks 的快速預覽。 Building Your Own Hooks:演示了使用自定義 Hooks 重用程式碼。 [**]Making Sense of React Hooks](medium.com/@dan_abramo…):探索了 Hooks 解鎖的新可能性。 useHooks.com:展示社群維護的 Hooks 清單和 demo。

JavaScriptCore

React Native 使用新的 JSC(JavaScriptCore)為應用程式提供支援。眾所周知,Android 上的 JSC 已經存在了幾年,這意味著很多現代 JavaScript 功能都不受支援。更糟糕的是,與 iOS 的現代 JSC 相比,它表現不佳。隨著這個版本的釋出,Android的JSC將帶來革命性的改變。 並且在 @DanielZlotin,@ dulmandakh,@ gengjiawen,@kmagiera 和 @kudo 等大神的努力下,Android 的 JSC 還將支援 64 位晶片,同時效能也大幅改進。

更快的啟動與內聯需求

新版本帶來了更高的效能,因此應用的啟動速度更快,這是因為新版本允許開發者根據需要載入資源。此功能稱為“內聯需求”(inline requires),因為它允許 Metro 識別延遲載入的元件。並且具有深入和多樣化元件架構的應用程式將獲得最大的改進。

在這裡插入圖片描述

當升級到 0.59.0版本時,工程會有一個新的 metro.config.js 檔案;將選項設定為 true 並向我們提供反饋!更多資訊可以參考文件 Performance

精簡核心庫

React Native重構的重要內容就是精簡核心庫,對於一些非核心的元件和內容,React Native會將其作為外掛包方式進行隔離。

眾所周知,React Native 是一個龐大而複雜的專案,具有複雜的 repository,為了加快應用的啟動速度,精簡核心庫是我們所做的一些努力,通過將程式碼遷移到單獨的庫以更好地管理來解決這些問題。

在這裡插入圖片描述

改進的Cli

React Native 的命令列工具是開發人員進入生態系統的入口點,但它們長期存在問題並且缺乏官方支援。新版本的Cli腳手架 工具已移至新的 repository,由一組專門的維護人員進行維護和開發。

在這裡插入圖片描述

React Hooks

此次版本,讓我最感興趣的就是React Hooks。具體來說,React Hooks是前端的技術,但是React Native也支援React Hooks,可以說FaceBook是在模糊React和React Native的界限,未來這二者的區別將越來越小。

所謂React Hooks,就是在 react 函式元件中,也可以使用類元件(classes components)的 state 和 元件生命週期,而不需要在 mixin、 函式元件、HOC元件和 render props 之間來回切換,使得函式元件的功能更加實在,更加方便我們在業務中實現業務邏輯程式碼的分離和元件的複用。

事實上,設計React Hooks是為了解決以下幾個問題:

  • 很難複用邏輯(只能用HOC,或者render props),會導致元件樹層級很深;
  • 會產生巨大的元件(指很多程式碼必須寫在類裡面);
  • 類元件很難理解,比如方法需要bind,this指向不明確。
  • ...

並且,React Hooks確實有著明顯的優勢:

  • 可以更好的減少程式碼量;
  • 同時降低程式碼在生命週期執行過程中造成的阻塞;
  • 自定義 Hooks 可以在一定程度上解耦,增加複用,減少巢狀;
  • 函數語言程式設計的風格讓函式功能獨立,程式碼簡潔更好閱讀。

具體來說,在React Native新版本中,React Hooks 提供了以下幾個最常用預設介面: useState:在函式中快速新增狀態; useEffect:快速新增生命週期處理; useImperativeHandle:快速對外暴露介面

借用React Hooks,開發者可以在一定程度上節省大量的程式碼,並且提供清晰的狀態管理邏輯。例如:

import React, {Component, useReducer, useRef, useImperativeHandle, forwardRef} from 'react';
import {Text, View, TouchableOpacity,} from 'react-native';

const initialState = {count: 0};

function reducer(state, action) {
    switch (action.type) {
        case 'reset':
            return initialState;
        case 'increment':
            return {count: state.count + 1};
        case 'decrement':
            return {count: state.count - 1};
        default:
            return state;
    }
}

export function DemoCounter({initialCount}) {
    const [state, dispatch] = useReducer(reducer, {count: initialCount});
    return (
        <View>
            <Text>Count: {state.count}</Text>
            <TouchableOpacity onPress={() => dispatch({type: 'reset'})}>
                <Text>Reset</Text>
            </TouchableOpacity>
            <TouchableOpacity onPress={() => dispatch({type: 'increment'})}>
                <Text>+</Text>
            </TouchableOpacity>
            <TouchableOpacity onPress={() => dispatch({type: 'decrement'})}>
                <Text>-</Text>
            </TouchableOpacity>
        </View>
    )
}
複製程式碼

由於Hooks 內部利用了陣列來實現狀態資料的順序更新,所以使用Hooks 時不能在迴圈或者條件判斷中使用。因為 Hooks 內的陣列每次都是順序的呼叫的,如果在條件判斷中打亂了順序,將導致遊標無法匹配到正確的資料,所以約定了不要在 if 或者 for 中使用 useState 等行為。

由於React Hooks是一個新的內容,我對React Hook理解也不是很深入,具體可以參考 React Hooks 官網或者深入理解React Hooks

參考:

React Hooks

Facebook 正在重構 React Native,將重寫大量底層

庖丁解牛!深入剖析 React Native 下一代架構重構

攜程開源RN開發框架CRN

相關文章