日常及初入React Native開發問題總結

語言: CN / TW / HK

theme: channing-cyan highlight: a11y-dark


前言

  • 作為一個開發人員,在開發過程中肯定會遇到各種各樣的技術問題,尤其在使用一個新的技術的時候。本文記錄了一些我最近遇到的一些思考和問題,包含一些低階的錯誤,我們應該避免。

迴圈引用

  • CommonJS 和 ES6 模組化有什麼區別?
  • 在模組 A 裡面引用模組 B,又在模組 B 中引用 A,由於 ES Module 是編譯時執行,所以迴圈引用會導致程式異常。例如: ``` // A.js import { bname } from './B.js'; console.log('A Module,bname=', bname); export const aname = 'A';

// B.js import { aname } from './A.js'; console.log('B Module,aname=', aname); export const bname = 'B'; ```

程式碼效能

  • 實現同樣的功能,不同的寫法效能肯定是不一樣的。

1:提前返回

  • 例如當我們需要查詢一個值是否在一個數組的某個物件中時,我們會去遍歷,遍歷的方式就有很多可以選了,例如:forEach、map、for、for...of、for...in等等。
  • for, for...in,for...of,forEach, map 的區別? const target = '' const list = [] // 正常寫法 list.forEach(item => { if(item.key === target){ // ... } }) // 優化 const len = list.length for(let i = 0; i < len; i ++) { if(item.key === target){ // ... break; } }

例2:有更快的方法

  • 原生的 Dom 操作大家肯定都很熟悉了,常用的 document.addEventListenerdocument.querySelector... 等等。新增的 API 有更強大的功能,但如果針對某些特定的條件,我們應該選擇更快的 API// 功能更全、更強的 document.querySelector document.querySelectorAll ... // 更快的 document.getElementById document.getElementsByClassName ...

清除指定路徑、域名下的 cookie

  • 當我們需要儲存用於其他網站登入的 cookie 時,我們需要存到指定的路徑下,不用時清除對應的 cookie
  • 設定 cookie 為已過期後,瀏覽器會自動清除對應的 cookie const clearCookie = (path = '/', domain = document.domain) => { const keys = document.cookie.match(/[^ =;]+(?==)/g); const overdueTime = new Date(0).toUTCString(); if (keys) { const len = keys.length; for (let i = 0; i < len; i++) { document.cookie = `${keys[i]}=0;path=${path};expires=${overdueTime}`; // 清除當前域名下的 document.cookie = `${keys[i]}=0;path=${path};domain=${document.domain};expires=${overdueTime}`; // 清除當前域名下的 document.cookie = `${keys[i]}=0;path=${path};domain=${domain};expires=${overdueTime}`; // 清除指定域名下 } } };

npm包無法安裝

公共包

  • 正常我們安裝的包都是從 npm 的官方映象源(https://registry.npmjs.org/)下載的,但由於有些包是在國外,所以下載很慢甚至會出現失敗。 // 1. 切換 taobao 映象源 npm config set registry https://registry.npm.taobao.org // 2. 使用 cnpm // 3. 開啟翻牆/代理

私有包

  • 當我們需要安裝一些私有釋出的包(例如公司內部封裝釋出的)時,使用 yarn 等工具安裝提示失敗時。 // 1. 修改 yarn.lock 找安裝成功的人看是否提交了對應的yarn.lock檔案,修改對應包的檔案配置,重新安裝即可。 // 2. 設定映象源為內部映象源地址 npm config set registry [內部映象源地址]

Chrome 除錯手機端 h5

  • 使用Chrome://inspect除錯 Android 裝置上Webview
  • 注意:
    1. 需要手機開啟一個 h5 頁面;
    2. 手機和電腦連同一網路;
    3. App 內無法除錯找原生(Android、iOS開發人員)看一下對應的包是否有問題;
    4. 進去一直白屏,開啟翻牆/代理。

React Native 相關

  • 最近做 React Native 的開發遇到的一些問題。

App 返回攔截未生效

  • 除錯攔截 App 內觸發返回操作時,不要在 App 首頁除錯,App 首頁會觸發 App 的退出功能。

Chrome除錯 VS 真機除錯

  • 由於之前沒做過 React Native 的開發,對它的執行機制不是很瞭解,導致出現了一個問題(判斷手機的系統)。
  • 我在本地開發使用的 Chrome 瀏覽器中除錯,所以我使用的是window.navigator.userAgent 來判斷,除錯也沒有任何問題。 export function isAndroid_ios() { let u = window.navigator.userAgent let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) //ios終端 let isIOS1 = u.indexOf('iPhone') > -1 || u.indexOf('iOS') > -1 return isiOS || isIOS1 ? 'ios' : 'android' }
  • 當我釋出後在手機上卻導致功能無法使用,通過不斷排查才找到問題原因就是手機上無法使用 window.navigator.userAgent。要使用 React Native 中的 Platform,通過它的 OS 屬性來判斷。 ``` // 使用 import { Platform } from 'react-native'; Platform.OS === 'ios' ? 'ios' : 'other';

// 原始碼部分 export const Platform: | PlatformIOSStatic | PlatformAndroidStatic | PlatformWindowsOSStatic | PlatformMacOSStatic | PlatformWebStatic;

// 以 PlatformIOSStatic 為例 interface PlatformIOSStatic extends PlatformStatic { constants: PlatformConstants & { forceTouchAvailable: boolean; interfaceIdiom: string; osVersion: string; systemName: string; }; OS: 'ios'; isPad: boolean; isTVOS: boolean; Version: string; } `` - **原因是兩者使用的JavaScript引擎不同。當在Chrome中使用遠端除錯時,它幾乎在瀏覽器中執行RN應用程式(然後使用V8 JavaScript 引擎)並通過WebSockets與模擬器(或裝置)通訊。如果在沒有啟用遠端除錯的情況下執行,它將使用JavaScript Core。這些環境之間存在許多差異,這些差異可能會導致不一致,所以不要僅僅依靠啟用JS` 除錯來執行應用程式,它可能會給您帶來錯誤錯誤或隱藏實際會導致實際裝置出現問題的錯誤。** - JavaScriptCore學習之JavaScriptCore

螢幕展示方向設定

獲取螢幕的寬高

  • 通過 react-native-orientation 中的addOrientationListener 方法可以監聽螢幕方向的變化,執行下面獲取函式。 ``` import { Dimensions } from 'react-native';

// Dimensions.get('window').height 皆為無劉海高度(含安全區及全面屏模式) // Dimensions.get('screen').height 皆為有劉海高度(含安全區及全面屏模式) // ExtraDimensions.get('REAL_WINDOW_HEIGHT')* 皆為含劉海高度(含安全區及全面屏模式)

export function getCurrentScreen(mode: 'window' | 'screen' = 'screen') {   const width = Dimensions.get(mode).width;   const height = Dimensions.get(mode).height;   return [width, height]; } ```

App 前臺、後臺執行狀態

  • React Native AppState // React Native import { AppState } from 'react-native'; const _handleAppStateChange = (nextAppState) => { if (nextAppState !== null) { if ( nextAppState === 'active') { // 前臺 // ... } else if ( nextAppState === 'background') { // 後臺 // ... } } } // Web document.addEventListener("visibilitychange", () => {     if (document.hidden) { // 後臺       // ...     } else { // 前臺 // ...     } });

往期精彩

「點贊、收藏和評論」

❤️關注+點贊收藏+評論+分享❤️,手留餘香,謝謝🙏大家。