??如果你喜歡我的文章,希望點贊?? 收藏 ?? 評論 ?? 三連支持一下,謝謝你,這對我真的很重要!
React Native 開發時,如果只是寫些簡單的頁面,基本上按著官方檔案 reactnative.dev就能寫出來,但是 React Native 的 API 有幾百個,沒有一定的開發踩坑經驗,面對一些新的需求時確實會抓不到重點,
本文總結了我個人開發 React Native 中遇到的問題和一些冷門的 API,如果有有緣人看到這篇文章并解決了實際問題,那就最好不過了,
一、內置組件
本節內容主要是是對官網 React Native Core Components 內容的補充,主要是說一些讓人開發體驗不爽的地方,幫助后來人避坑,
1.View
View 組件作為最基礎的組件,撐起了 RN 頁面的半壁江山,在使用的程序中有幾個屬性比較冷門但個人認為挺有用的屬性,
hitSlop屬性:這個屬性可以擴大 View 的觸控范圍,在一些小按鈕上用收益還是很大的pointerEvents屬性:這個屬性類似 CSS 的pointer-events屬性,可以控制 View 對 touch 事件的回應
2.Text
Text 組件是很常用的屬性,有幾個小點需要開發者注意一下:
Android 上存在吞字現象,現象是部分機型上最后一個字符不顯示,原因不明,目前的折衷方案是文字的最后一行多加一個空格 or 零寬字符 Android 有個屬性叫 includeFontPadding,設定為 false 后可以減少文字上下的 padding(這個 padding 是為角標字符預留的,例如 H?O、2??),這樣可以更好的實作上下垂直居中對齊實作文字的居中對齊時,最好用一個 View嵌套一個Text標簽,然后給View設定一些 flex 屬性控制Text居中對齊,Web 開發中經常使用 lineheight 屬性實作單行文字的垂直居中對齊,這種實作方式本來就是權宜之計,在 RN 上行不太通,最佳實踐還是利用 flex 屬性實作居中對齊字體的配置相對來說比較麻煩,有個不錯的教程 Ultimate guide to use custom fonts in react native 可以參考一下
3.TextInput
輸入框組件也是很常用的屬性,個人用下來有幾個不爽的地方:
iOS/Android 的默認樣式差距比較大,不做封裝的話會寫非常多的平臺相關代碼
placeholder的文字比較長時,若出現換行現象,沒有 API 去控制它的行高若一個頁面出現多個
TextInput組件時,需要用ScrollView組件包裹,才能實作不同TextInput組件焦點切換的功能
4.Image
Image 組件在表現上我個人認為非常優秀了,但在一些細節上初步上手的同學可能還是不太習慣:
沒有 CSS 那么多的濾鏡屬性,只支持模糊效果,不過個人基本沒遇到過影像濾鏡需求 加載網路圖片時,必須指定圖片寬高,若不設定尺寸默認為 0 Android 上圖片尺寸非常大時(貌似是 5000px?),圖片會直接加載不出來,不過這種場景很少很少,基本都會瓦片圖分步加載,要不然大圖會引起 OOM 的 iOS/Android 對 webp 的支持也不是開箱即用的,需要分別配置: iOS 使用 SDImageWebPCoder提供支持Android 使用 fresco提供支持具體配置方案可以參考 react-native-webp-format
Android 不支持點九圖
5.Modal
RN 官方之前提供的 Modal 組件有個很明顯的問題,Modal 無法覆寫到狀態欄,比如說我們做了一個彈窗,背景是黑色半透明的,但狀態欄是白色的,這樣在感官上就非常的割裂,
所幸 0.62 版本上了一個 statusBarTranslucent 屬性,設為 true 就可以覆寫到狀態欄之上,如果是 0.62 以下的版本,就需要改一些配置了,可以參考 stackoverflow 的這個回答:How to hide the statusBar when react-native modal shown?
6.ScrollView
ScrollView 組件是 RN 提供的滑動容器組件,有幾個比較冷門但是很好用的 API 我這里說明一下,
第一個是吸頂功能,涉及到 StickyHeaderComponent 和 stickyHeaderIndices 這兩個 API,可以實作滾動吸頂的效果,非常的好用,
第二個是 automaticallyAdjustContentInsets 屬性,有時候 iOS 滾動串列上會出現莫名其妙的空白區域,這個是 iOS Native 層實作的,RN 具體的觸發時機我沒有做詳細的測驗,但基本上把這個屬性關掉就可以規避了,
7.FlatList
FlatList 主要是注意 3 個點:
FlatList 提供自定義的頭部/底部/空白/分割線組件,比一般的 Web 組件封裝更徹底一些 React 渲染串列的時候會要求加 key以提高 diff 性能,但是 FlatList 封裝的比較多,需要用keyExtractor這個 API 來指定串列 Cell 的keyFlatList 性能優化的內容官網寫的不是很好,我之前寫了個更易懂的,有需求的同學可以了解一下
二、內置 API
本節內容主要是是對官網 React Native API 內容的補充,主要是說一些讓人開發體驗不爽的地方,幫助后來人避坑,
1.AppState
AppState 這個 API 在實際開發中主要是監聽 APP 前后臺切換的,這個 API 在 iOS 上表現符合語意,但是 Android 上就有問題了,因為 AppState 在 Android 端的實作其實是基于 Activity 的生命周期 的,
就比如說 AppState 提供的 background 這個狀態,其實是基于 Activity 的 onPause() 的,但是根據 Android 的檔案,onPause() 執行時有這么幾種場景:
APP 切換到系統后臺(符合預期) 當前 RN 容器 Activity 上層覆寫了新的 Activity(不符合預期) 當前 RN 容器 Activity 上層覆寫了 Dialog,例如權限申請彈窗(Dialog 本質上就是個半透明 Dialog)(不符合預期)
綜上所述,使用 AppState 監聽 APP 狀態時要充分考慮 Android 的這些“例外”表現是否會引起程式 BUG,
2.Permissions
APP 平臺的權限管理是一件很繁瑣的事情,RN 官方只提供了 PermissionsAndroid,沒有提供跨平臺的權限管理 API,使用時很不方便,這里我建議使用 react-native-permissions 這個庫,管理權限更便捷,
3.Event
RN 官網上沒有暴露 Event 相關的 API,但是 RN 已經對外匯出了 DeviceEventEmitter 這個「發布-訂閱」事件管理 API,使用也很簡單,如下案例使用即可,
import { DeviceEventEmitter } from 'react-native';
// 觸發
DeviceEventEmitter.emit('EVENT');
// 監聽
const listener = DeviceEventEmitter.addListener( 'EVENT', () => {});
// 移除
listener.remove()
4.Animated
RN 的影片 API,說實話掌握成本比較高,單官方 API 就涉及到 Animated、LayoutAnimation、Easing、useNativeDriver 等概念,而且檔案分布比較分散,初學者很難在腦海里構建一個完整的腦圖,
如果你想構建性能更高的影片,還得學習 react-native-gesture-handler、react-native-reanimated 等第三方庫的 API,學習成本直線飆升,
這里我推薦 React Native Animation Book 這本在線書籍,基本上算是手把手教學,看完之后就對 RN 的影片 API 有個整體的認識了,
三、第三方 Library
React Native 陸陸續續把一些非核心的組件交給社區維護,例如 webview、async-storage 等,還有一些非官方但很好用的組件,例如 react-native-svg、react-native-camera 等等,
除了這些和 Native 相關的第三方庫,JS 社區里宿主無關的 JS 庫也是可以使用的,例如 lodash、redux 等純邏輯庫,
由于第三方庫太多了,所以我這里就不一一列舉了,
四、特效篇
React Native 的 style 樣式屬性只提供了基礎的布局屬性,例如 flexbox layout、fontSize 等等,但是很多 CSS3 的特效屬性,React Native 基本上都得引入第三方庫,我梳理了一下常用的幾個 UI 特效要用到的屬性和插件,方便開發者使用,
1.圓角效果
這個直接使用 View styles 屬性的 borderRadius 即可,RN 同時也支持設定 View 四個角的單獨弧度,
2.模糊效果
blur 效果要用到 @react-native-community/blur 這個 RN 官方社區庫,這個 RN 模糊庫比 CSS 的 blur() 屬性更強大一些,CSS 只支持高斯模糊,這個庫支持起碼三種模糊效果,不過具體效果還是要和 UED 商議,
3.陰影效果
陰影可以用 RN 提供的 Shadow Props,但是它是分平臺的:
iOS 提供了 shadowColor、shadowOffset、shadowOpacity和shadowRadius四個屬性,和 CSS 的 box-shadow 屬性完全對標,可以滿足絕大多數的場景Android 只提供了 shadowColor和elevation兩個屬性,而且從嚴格意義上來說,elevation其實是「仰角」的意思,是 Android 官方提供的屬性,模擬現實中的從上向下的光照引起的陰影變化,雖然理論一套一套的,但是在現實開發中就會發現,elevation搞出來的陰影非常丑,和 iOS 比起來完全是天壤之別,個人一般建議使用漸變替代陰影,
4.漸變效果
漸變要使用一個第三方庫:react-native-linear-gradient,正如庫名,這個倉庫只提供「線性漸變」的解決方案,以個人經驗,線性漸變在絕大部分情況下都足夠了,如果要使用「徑向漸變」,可以使用 react-native-svg 的 RadialGradient 組件,
五、可視化篇
Web 平臺除了最基礎的 <p/> <img/> 標簽,還支持 SVG、canvas 這些自由度較高的繪制 API,它們支持最多的就是可視化場景,例如各種自定義影像和圖表,下面就簡單介紹一下 RN 中對標 Web 的的一些第三方庫,
1.SVG
RN 的 SVG 支持是基于 react-native-svg 這個倉庫,就個人的使用體驗來說,基本和 Web 的 SVG 功能沒啥兩樣,除了自繪一些自定義 SVG,它更多的功能是作為底層庫支持上層圖表的使用,
2.類 canvas
RN 中是沒有 canvas 這個概念的,市面上也沒有很好用的 canvas 替代品,有開發者搞出了 react-native-skia,也有一些 demo 展示,但它目前其實還是一個實驗性專案,上生產環境風隙訓是太大了,不過就我個人經驗來說,很多繪制功能都能基于 SVG 實作,必須用 canvas 的情況應該并不多見,
??基于 skia 你再把 flutter 集成進去,可以玩套娃游戲了 :)
3.OpenGL 支持
在移動端平臺上,WebGL 就是瀏覽器平臺對 OpenGL ES 的封裝,RN 本身已經很貼近 Native 平臺了,就沒必要舍近求遠支持 WebGL 了,直接支持 OpenGL ES 就好,
目前 RN 對 OpenGL 的支持是基于 gl-react 的,底層的適配層是基于 expo-gl,網上有個 gl-react 的 demo 教程,有需要的讀者可以學習一下,
??因為個人沒做過 RN 3D 相關的需求,所以也無法對該庫得出一個準確的評價,需要讀者自行判斷
4.圖表功能
圖表是個很現實的需求,在一些 B 端場景上經常會有報表需求,因為 RN 只有 SVG 支持比較完善,所以 RN 的圖表基本都是基于 SVG 繪制的,
Web 上基于 SVG 的圖表庫有很多,但是 RN 能用到的可能沒有幾個,主要原因是 RN 和 Web 的宿主環境不一樣,一些圖表庫可能會用到 Web 特供 API(例如 getElmentById),像 ECharts 這樣的庫 RN 肯定是用不了的,
可遷移使用的庫一般要滿足兩個條件:
純邏輯: D3.js一些純邏輯的庫,只用到 JS 的語言能力,例如 d3-scale平臺無關:直接基于 React 構建,沒有用到平臺特有 API,例如 victory-native
這里有一個基于 D3.js 實作的股票箱型圖的視頻教程,感興趣的讀者可以了解一下,
5.海報功能
海報分享是現如今非常常見的一個前端功能,網頁基本是基于 canvas 生成分享海報的,RN 雖沒有較好的 canvas API,但是有個不錯的庫——react-native-view-shot,可以把 RN 寫的 View 生成一張圖片,借用這個庫就能在 APP 本地生成圖片,轉而實作海報功能,
推薦閱讀
RN 性能優化系列目錄:
?? React Native 性能優化——Render 篇 ?? React Native 啟動速度優化——Native 篇 ?? React Native 啟動速度優化——JS 篇
??如果你喜歡我的文章,希望點贊?? 收藏 ?? 在看 ?? 三連支持一下,謝謝你,這對我真的很重要!
歡迎大家關注我的微信公眾號:鹵蛋實驗室,目前專注前端技術,對圖形學也有一些微小研究,
也可以加我的微信 egg_labs,歡迎大家來撩,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/303774.html
標籤:其他
上一篇:Web應用開發之CSS(1)
