关于react-native:在React-Native应用中实现Android内购功能

<article class=“article fmt article-content”><blockquote>首发于公众号 <strong>前端混合开发</strong>,欢送关注。</blockquote><p>编者注:本文于2023年9月21日更新,移除了对现已弃用的 expo-in-app-purchases 库的提及。当初建议您应用 react-native-iap 或 react-native-purchases ,咱们在本文中都有探讨。</p><p>利用内购买(IAP)曾经扭转了挪动利用的盈利形式。它不仅为开发者和企业解锁了新的支出起源,还使开发者可能为用户发明更具吸引力和沉迷感的体验。</p><p>有许多基于 Google Play 计费库和苹果的 StoreKit 框架构建的 React Native IAP(利用内购买)包,能够让你轻松地将利用内购买集成到你的利用中。然而,咱们将通过一系列步骤来探讨如何将 react-native-iap 集成到你的 React Native 利用中,这波及构建一个简略的食谱应用程序;在这里找到 GitHub。</p><h2>概述:利用内购买</h2><p>利用内购买是用户能够间接在你的利用内购买的额定内容、性能、订阅或服务。换句话说,它是一种利用货币化模型,容许咱们收费或以较低成本提供你的应用程序,给予用户无需事后财务承诺就能应用利用的机会,并通过进行利用内购买解锁额定性能或内容的选项。</p><p>利用内购买是通过连贯到利用商店计费零碎的领取网关来实现的。计费和交易过程齐全由利用商店治理,使用户可能平安地进行交易。</p><p>IAP 提供了极大的灵活性。无论你是在开发电子商务平台、生产力利用还是媒体平台,都能够利用 IAP 来开释你利用的全副货币化后劲。一些常见的利用内购买示例包含:</p><ul><li>虚构产品:如虚构货币、扩大包、游戏晋升等虚构物品,用于加强用户体验</li><li>锁定性能:利用可能有一个收费的根底版本供普通用户应用,以及一个付费的业余版本,该版本提供了只能通过利用内购买解锁的额定性能,以吸引寻求更残缺体验的用户</li><li>订阅:为了定期取得对独家内容或服务的拜访权而收取的周期性费用,即费用是每月的,到了结算周期的开端,订阅费用会主动收取,以持续取得对产品或服务的拜访权。</li></ul><p>此外,IAP容许你依据各种条件(如购买历史)为选定的用户群体创立个性化的优惠,以最大化收益,并为你的用户提供更相干的体验。</p><h2>IAP 的类型</h2><p>在设置IAP之前,你应该了解有三大类的利用内购买:</p><ul><li>消耗品:这种类型的利用内购买是为一次性应用而设计的。因而,用户能够在物品用完后再次购买——例如,虚构货币、助推器和虚构礼物。</li><li>非消耗品:这些是只须要购买一次并且永恒关联到用户账户的物品 - 例如,广告移除,处分章节和自定义设置</li><li>订阅:如前所述,这种利用内购买形式容许用户定期领取反复费用,以获取高级性能或独家内容的拜访权限</li></ul><h2>对于咱们的食谱应用程序</h2><p>要顺利追随本文进行,你应该具备以下条件:</p><ul><li>React Native的常识</li><li>一个谷歌开发者账户</li><li>在你的开发机器上设置React Native环境</li><li>一个安卓设施</li></ul><p>为了演示如何将利用内购买集成到React Native利用中,咱们将开发一个食谱利用,该利用为收费用户显示无限的食谱列表,并提供利用内购买选项,通过高级订阅解锁所有食谱。</p><p>该应用程序由三个屏幕组成:</p><ul><li>首页:显示食谱列表,并蕴含一个按钮,该按钮会疏导用户到付费墙屏幕,在那里用户能够购买高级订阅</li><li>菜谱详情:这个界面展现了菜谱的具体概览,包含所需的食材和制作步骤</li><li>付费墙:这显示了用户能够购买的可用内购产品</li></ul><p>应用程序的初始我的项目在GitHub上可用。咱们将在其根底上开发应用程序内购买局部,这将贯通文章的其余部分。</p><p>运行以下命令来克隆启动我的项目:</p><pre><code>git clone -b start https://github.com/emmanuelhashy/RecipeApp.git –single-branch</code></pre><h2>创立咱们的IAP产品</h2><p>要将IAP集成到你的应用程序中,你首先须要在各自的商店中设置产品。这些商店作为一个核心,用于配置和治理在你的应用程序中向用户展现的产品。</p><p>在这个例子中,咱们将介绍如何在Google Play控制台为Android设施设置产品的步骤。为了在开发过程中无缝测试利用内购买,你须要将你的利用公布到内部测试轨道。</p><p>在Google Play控制台中,设置一个商户账户以在您的利用中承受付款。之后,在“All apps”页面的已公布利用列表中抉择您的利用。</p><p></p><p>在应用程序仪表板中,滚动到侧边栏的 <strong>创收</strong> 局部并抉择 <strong>商品</strong> 下拉按钮。能够依据您的IAP产品类型抉择 <strong>利用内产品</strong> 或 <strong>订阅</strong> 。在这个例子中,咱们将抉择“利用内产品”。</p><p></p><p>当初,在利用内产品页面上,点击创立产品按钮以创立新产品:</p><p></p><p>提供产品所需的属性,包含产品 ID、名称、形容和价格。之后,点击“保留”,而后点击“激活”以使产品可供购买。你会想复制产品的 ID,因为咱们稍后会在利用中应用它:</p><p></p><p>你当初应该能在产品概览页面看到你的产品。你能够在此页面创立尽可能多的产品。</p><h2>增加许可证测试员</h2><p>许可证测试员是一个账户,容许你在受控环境中与利用内购买进行交互。在开发过程中,你能够应用许可证测试员来测试和验证你的利用内购买是否失常工作,而无需进行理论领取。</p><p>在你的 Google Play 控制台中,导航至许可证测试页面,能够通过在搜寻栏中搜寻,或者从主控制台的仪表板侧边栏抉择许可证测试:</p><p></p><p>而后,点击“创立电子邮件列表”按钮,并为列表提供一个名称和测试账户的电子邮件地址。点击“保留更改”。</p><p></p><p>接下来,在应用程序仪表板的内部测试局部,点击测试人员选项卡,并增加您的测试人员列表:</p><p></p><p>抉择你之前创立的列表,而后点击保留:</p><p></p><p>接下来,点击页面底部的“复制链接”按钮,以复制给你的测试人员的邀请URL:</p><p></p><p>最初,在带有测试账户的设施上关上URL以承受邀请。</p><h2>装置 react-native-iap</h2><p>react-native-iap 库容许你在你的 React Native 利用中无缝实现利用内购买。它是围绕 Google Play 计费库和苹果 StoreKit 框架的封装。此外,通过这个库,你还能够集成来自亚马逊利用商店的 IAP 我的项目。</p><p>首先,在终端中运行以下命令来应用npm安装包:</p><pre><code>npm install react-native-iap</code></pre><p>装置后,须要进行一些额定的配置以实现包的设置。请返回 <code>android/build.gradle</code> ,并在 <code>buildscript.ext</code> 块中增加以下属性:</p><pre><code>androidXAnnotation = “1.1.0"androidXBrowser = “1.0.0"minSdkVersion = 24kotlinVersion = “1.6.0”</code></pre><p>而后,在依赖项块上面增加以下内容:</p><pre><code>classpath “org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion”</code></pre><p><code>react-native-iap</code> 容许你整合来自Google Play商店和Amazon Appstore的IAP产品。要启用Play商店的领取性能,请导航至 <code>android/app/build.gradle</code> ,而后在 <code>defaultConfig</code> 块下增加以下内容:</p><pre><code>missingDimensionStrategy “store”, “play”</code></pre><p>或者,你能够通过在Android块中增加以下属性来启用两个商店的领取性能:</p><pre><code> flavorDimensions “appstore” productFlavors { googlePlay { dimension “appstore” missingDimensionStrategy “store”, “play” } amazon { dimension “appstore” missingDimensionStrategy “store”, “amazon” } }</code></pre><h2>初始化连贯</h2><p><code>react-native-iap</code> 库的原生模块须要在应用程序生命周期的晚期进行初始化,即在进行任何与IAP相干的函数调用之前。这能够在应用程序的根组件中实现。</p><p>为了实现这个,将以下代码增加到你的 App 组件中:</p><pre><code>useEffect(() => { const init = async () => { try { await initConnection(); if (Platform.OS === ‘android’) { flushFailedPurchasesCachedAsPendingAndroid(); } } catch (error) { console.error(‘Error occurred during initilization’, error.message); } } init(); return () => { endConnection(); }}, [])</code></pre><p>在上述代码中,调用了 <code>initConnection</code> 函数来初始化包的原生模块。</p><p>另外,在文件中蕴含以下导入:</p><pre><code>import React, { useEffect } from ‘react’;import { Platform } from ‘react-native’;import { initConnection, endConnection, flushFailedPurchasesCachedAsPendingAndroid,} from ‘react-native-iap’;</code></pre><h2>定义产品SKU</h2><p>产品ID是集成利用内购买的要害组成部分。每一个都能惟一地标识一个可购买的产品。因为咱们的利用内购买产品的ID将在利用的不同中央应用,咱们须要在一个核心地位定义它。</p><p>在 <code>src/utils</code> 下创立一个名为 <code>constants.js</code> 的新文件,并增加以下代码:</p><pre><code>import { Platform } from “react-native"const productSkus = Platform.select({ android: [ ‘recipe_app_premium’ ]})export const constants = { productSkus};</code></pre><p>在这里,咱们定义了一个常量 <code>productSkus</code> ,借助 <code>Platform.select</code> 函数,正确地辨认出与设施操作系统对应的产品ID。咱们还提供了之前在 Google Play 控制台中创立的产品的产品ID。</p><h2>获取可用购买项</h2><p><code>react-native-iap</code> 提供了 <code>getAvailablePurchases</code> 性能,用于检查用户以后的购买状况。咱们能够应用这种办法来验证用户是否领有高级订阅,以解锁所有食谱的拜访权限。</p><p>关上 <code>src/screens/home.jsx</code> 并在 Home 组件中增加以下代码:</p><pre><code>useFocusEffect( useCallback(() => { setLoading(true); const getPurchase = async () => { try { const result = await getAvailablePurchases(); const hasPurchased = result.find((product) => product.productId === constants.productSkus[0]); setLoading(false); setPremiumUser(hasPurchased); } catch (error) { console.error(‘Error occurred while fetching purchases’, error); } } getPurchase(); }, []))</code></pre><p>在 <code>useFocusEffect</code> 钩子外部,咱们定义了一个 <code>getPurchase</code> 函数,该函数获取用户的可用购买并设置 <code>isPremiumUser</code> 状态为真,如果用户购买的产品的ID与咱们的高级产品的ID匹配。</p><p>另外,不要遗记蕴含以下的导入:</p><pre><code>import { getAvailablePurchases } from “react-native-iap”;import { constants } from “../utils/constants”;</code></pre><h2>增加内购产品</h2><p>目前,付费墙屏幕并未显示其前面的可用IAP产品。为了在这个屏幕上展现咱们的IAP产品,让咱们开始创立一个 ProductItem 组件来代表每一个IAP我的项目。</p><p>在 <code>src/components</code> 中创立一个名为 <code>productItem.js</code> 的文件。而后,增加以下代码:</p><pre><code>import React from “react”;import { View, StyleSheet, Text, Button } from “react-native”;const ProductItem = ({ title, onPress }) => { return ( <View style={styles.container}> <Text style={styles.title}>{title}</Text> <View style={styles.button}><Button title=‘Buy’ color=‘coral’ onPress={onPress}/></View> </View> )}export default ProductItem;</code></pre><p>该组件有两个属性 —— <code>title</code> ,是产品的名称,和 <code>onPress</code> ,一个启动购买的回调函数。</p><p>接下来,增加组件款式:</p><pre><code>const styles = StyleSheet.create({ container: { flexDirection: ‘row’, backgroundColor: ‘#fff’, height: 100, borderRadius: 10, elevation: 6, justifyContent: ‘space-between’, alignItems: ‘center’, padding: 10, marginTop: 30, marginHorizontal: 10 }, title: { color: ‘#000’, fontSize: 16, flex: 2.5, marginRight: 10 }, button: { flex: 1 }});</code></pre><p>而后,关上 src/screens/paywall.jsx 并在 Paywall 组件中增加以下内容:</p><pre><code>const [products, setProducts] = useState([]);const [isLoading, setLoading] = useState(true);useEffect(() => { const purchaseUpdateSubscription = purchaseUpdatedListener( async (purchase) => { const receipt = purchase.transactionReceipt; if (receipt) { try { await finishTransaction({ purchase, isConsumable: false }); } catch (error) { console.error(“An error occurred while completing transaction”, error); } notifySuccessfulPurchase(); } }); const purchaseErrorSubscription = purchaseErrorListener((error) => console.error(‘Purchase error’, error.message)); const fetchProducts = async () => { try { const result = await getProducts({ skus: constants.productSkus }); setProducts(result); setLoading(false); } catch (error) { Alert.alert(‘Error fetching products’) } } fetchProducts(); return () => { purchaseUpdateSubscription.remove(); purchaseErrorSubscription.remove(); } }, [])</code></pre><p>咱们合成下面的代码块是做什么的:</p><ul><li>首先,咱们定义两个状态 — <code>products</code> 和 <code>isLoading</code> — 用于存储IAP我的项目和正在获取的IAP我的项目的加载状态</li><li>在 <code>useEffect</code> 钩子中,咱们定义了两个监听器 — <code>purchaseUpdatedListener</code> 和 <code>purchaseError</code> — 来监听胜利的购买和在过程中可能产生的任何谬误。通常,你应该在启动任何购买事件之前注册这些监听器。</li><li>在 <code>purchaseUpdatedListener</code> 中,咱们定义了一些自定义逻辑来解决与咱们后端的收据验证</li></ul><p>在钩子中,咱们应用 <code>fetchProduct</code> 函数获取可用的产品,该函数围绕 <code>react-native-iap</code> 中的 getProducts 函数。而后,产品的状态会依据返回后果进行更新。</p><p>最初,咱们确保在组件卸载时移除监听器。</p><p>接下来,增加以下函数,该函数在购买实现时执行:</p><pre><code>const notifySuccessfulPurchase = () => { Alert.alert(“Success”, “Purchase successful”, [ { text: ‘Home’, onPress: () => navigation.navigate(‘Home’) } ])}</code></pre><p>而后,增加上面的代码来解决购买:</p><pre><code>const handlePurchase = async (productId) => { setPurchaseLoading(true) try { await requestPurchase({ skus: [productId] }); } catch (error) { Alert.alert(‘Error occurred while making purchase’) } finally { setLoading(false); }}</code></pre><p>上述函数通过提供正在购买的商品的产品ID来调用 <code>requestPurchase</code> 函数,以启动一个IAP。</p><h2>更新付费墙</h2><p>最初,将付费墙的JSX更新为以下内容:</p><pre><code><View style={styles.container}> { !isLoading ? <> <View style={styles.header}> <Image source={backgroundImage} style={styles.image} /> <View style={styles.heading}> <Text style={styles.text}>Unlock all Recipes</Text> <Text style={styles.subText}>Get unlimited access to 1000+ recipes</Text> </View> </View> {products.map((product, index) => ( <ProductItem key={index} title={product.title} onPress={() => handlePurchase(product.productId)} /> ))} </> : <View style={styles.indicator}> <ActivityIndicator size=‘large’ /> </View> }</View></code></pre><p>在文件中蕴含以下导入:</p><pre><code>import React, { useEffect, useState } from “react”;import { View, StyleSheet, Text, Image, Alert, ActivityIndicator } from “react-native”;import { constants } from “../utils/constants”;import { getProducts, //For fetching available products requestPurchase, //For initiating in-app purchases purchaseUpdatedListener, //For listening to purchase events purchaseErrorListener, //For listening to purchase errors finishTransaction //For acknowledging a purchase} from “react-native-iap”;import ProductItem from “../components/productItem”;</code></pre><h2>运行 React Native 利用</h2><p>当初你曾经实现了利用内购买的设置,是时候运行应用程序了。为了做到这一点,确保你的安卓设施已连贯到你的开发机器。尽管你能够应用模拟器来实现这一点,但咱们倡议你在实在设施上测试利用内购买。</p><p>当初,在你的终端运行以下命令:</p><pre><code>npx run react-native run-android</code></pre><p>你应该能看到与上面相似的输入,并可能发动利用内购买:</p><p></p><h2>总结</h2><p>在你的React Native应用程序中实现利用内购买能够解锁额定的支出起源,而且,如果实现切当,还能够晋升你的用户体验。</p><p>咱们曾经通过逐渐领导,介绍了如何应用 <code>react-native-iap</code> 库轻松地将利用内购买集成到您的React Native利用中。如果您想思考另一种办法,或者想在iOS利用中实现IAP,请查看咱们对于应用expo-in-app-purchases实现IAP的帖子。</p><h3>交换</h3><blockquote><p>首发于公众号 大迁世界,欢送关注。 每周一篇实用的前端文章 ️ 分享值得关注的开发工具 ❓ 有疑难?我来答复</p><p>本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。</p></blockquote><p></p></article> ...

March 5, 2024 · 4 min · jiezi

关于react-native:从零开始构建React-Native数字键盘功能

首发于公众号 前端混合开发,欢送关注。古代挪动应用程序在入门过程中常常波及一个步骤,你须要输出发送到你的电子邮件或手机号码的验证码 PIN。有时,你须要应用相似于宰割 OTP 输出字段的货色来输出 PIN。另一种输出验证码 PIN 的形式是应用拨号盘。 "OTP" 指的是 "一次性明码" (One-Time Password)。这是一种平安机制,用于通过短信或电子邮件向用户发送一次性应用的明码或验证码,以验证用户的身份。在这篇文章中,咱们将展现如何为 React Native 利用创立一个定制的数字键盘。构建一个定制的 React Native 数字键盘能够作为宰割输出或传统 TextInput 元素的优良替代品,以个性化你的挪动利用设计。 你能够查看咱们的React Native我的项目的残缺源代码,并随着咱们一步步设置数字键盘进行跟踪。让咱们开始吧。 在React Native利用中数字键盘的应用场景在React Native利用中,有许多业余的数字键盘应用场景。 一个常见的例子是一次性明码(OTP)输出验证。例如,假如你在新用户入门过程中,向他们的手机发送了一个OTP。发送OTP后,用户将被疏导到一个屏幕上,应用数字键盘输入并验证它。 另一个应用场景是为你的利用增加一层平安防护,这对于蕴含敏感信息的利用来说十分重要。当你的用户从新登录你的利用时,你能够为他们展现一个数字键盘,他们能够在此输出一个PIN码,你的利用在让他们登录前须要验证这个PIN码。 在咱们的教程中,咱们将创立这第二种用例的一个简略示例。咱们将看到如何在 React Native 中从头开始设置一个数字键盘,以便用户能够创立一个 PIN 并应用该 PIN 登录利用。 设置开发环境运行以下命令以疾速启动一个Expo利用: npx create-expo-app my-app上述命令将创立咱们所需的根底React Native我的项目文件。实现后,启动iOS或Android模拟器上的开发服务器: //for iOSnpm run ios //for Androidnpm run android 这是你我的项目文件夹中 App.js 文件内代码的输入。 创立、渲染和设计React Native数字键盘在这个局部,咱们将开始创立三个屏幕: Login , CustomDialpad 和 Home 。 Login 屏幕将是用户首次加载利用时看到的第一个屏幕。它将有一个按钮,能够将用户疏导到 CustomDialpad 屏幕,在那里他们能够输出他们的PIN码。一旦输出正确的PIN码,利用将会将用户疏导到 Home 屏幕。 咱们开始构建咱们的React Native应用程序,蕴含这三个屏幕。首先,装置咱们须要设置和配置React Native根本导航的以下包: npx install @react-navigation/native @react-navigation/native-stack react-native-safe-area-context react-native-screens另外,创立一个名为 screens 的文件夹,并在其中放入三个文件: Login.jsx , CustomDialPad.jsx 和 HomeScreen.jsx 。 ...

February 29, 2024 · 6 min · jiezi

关于react-native:在React-Native中构建启动屏

首发于公众号 前端混合开发,欢送关注。在这个教程中,咱们将演示如何在React Native中构建一个启动屏幕。咱们将领导你如何应用 react-native-splash-screen 为iOS和Android利用构建杰出的欢送界面。此外,因为Expo很受欢迎,许多人经常抉择应用它,咱们也将探讨如何在Expo中构建启动屏幕。 什么是启动画面?启动画面是用户拜访应用程序其余性能之前呈现的第一个屏幕。能够说,启动画面是让您的挪动利用的品牌名称和图标深刻用户记忆的最佳形式。 在网络应用中,咱们应用预加载器为用户提供动画娱乐,同时服务器操作正在解决中。只管这听起来很间接,但它是构建和保留用户群的要害工具。 在React Native中创立启动屏有很多益处。例如,思考一个从API加载数据的场景。在用户期待时显示加载器是一种良好的用户体验。同样的状况也实用于启动屏,因为在应用程序启动时立刻显示加载器能够帮忙你在用户期待应用程序准备就绪时,向他们展现一个有组织的,设计良好的显示界面。 对于这个 react-native-splash-screen 演示,咱们将为Android 和 iOS 构建一个启动屏幕。本教程将领导你如何筹备适合的图片大小,更新必要的文件,并在利用加载时暗藏启动屏幕。实现后的利用将如下图所示 为什么启动画面的图片大小很重要为挪动利用创立启动画面可能会有些辣手,你必定不心愿因为启动画面分辨率的不统一在某些设施上呈现显示问题。例如,安卓设施的需要与iOS齐全不同。大多数有教训的设计师能够从零开始为两种设施创立所需的启动画面分辨率。 然而,有许多可用的第三方工具能够帮忙你为Android和iOS创立启动屏幕。在这个教程中,咱们将应用 App Icon Generator,这是一个用于创立Android和iOS利用图标和图片的在线平台。 在你持续之前,请确保你有一张高清的,2000x2000像素(72 PPI)的图片筹备好。你能够在GitHub上克隆这些教程的残缺源代码。 构建一个React Native启动屏幕首先,返回Appicon。将你的图片拖到提供的框中,而后抉择4x作为你的根底尺寸。勾选 iOS 和 Android,而后点击生成: 接下来,解压下载的文件,并将 iOS 和 Android 文件夹复制到你克隆的启动我的项目的 assets 目录中的 assets 文件夹里: 在React Native 中构建启动屏须要一些微调。首先,应用上面的任一命令装置 react-native-splash-screen 包: /* npm */npm i react-native-splash-screen --save/* yarn */yarn add react-native-splash-screen为iOS构建一个启动屏幕在你的终端中,应用上面的命令链接依赖项: cd ios // to enter into IOS directorypod install接下来,导航到 AppDelegate.m 文件并用以下代码进行更新。增加代码 #import "RNSplashScreen" (第6行),并将默认设置为显示启动屏 [RNSplashScreen show] (第41行)。请参考上面代码中的正文: ...

February 26, 2024 · 4 min · jiezi

关于react-native:React-Native框架开发介绍以及其优点

大家好,我是咕噜铁蛋,在明天的文章中,我通过科技伎俩和大家一起探讨一下React Native框架的开发介绍以及其长处。我深知抉择适合的开发工具对于我的项目的胜利至关重要。而React Native作为一款风行的跨平台挪动利用开发框架,其独特之处和长处值得咱们深刻理解和探讨。一、React Native框架的简介首先,让咱们来简略介绍一下React Native框架。React Native是由Facebook开发的一款基于React的挪动利用开发框架。它容许开发者应用JavaScript和React的语法进行挪动利用的开发,并将代码转换为原生平台的组件。通过React Native,开发者能够在不同平台上共享大部分代码,从而实现疾速的跨平台开发。二、跨平台开发劣势React Native框架最大的长处之一就是跨平台开发的能力。应用React Native开发挪动利用,能够实现一次编写,多平台运行。无论是iOS还是Android,只须要编写一套代码,即可适配不同平台,缩小了开发和保护老本,晋升了开发效率。三、热更新和疾速迭代React Native框架反对热更新和疾速迭代,这是开发者十分看重的一点。热更新意味着开发者能够在不从新公布利用的状况下实时更新UI和性能。这种灵活性和高效性使得开发团队可能更快地响应用户需要,推出新性能,并及时修复bug,从而晋升了产品的竞争力和用户满意度。四、生态丰盛和社区反对React Native领有宏大的生态系统和沉闷的开发社区,这为开发者提供了丰盛的资源和反对。在React Native社区中,你能够找到各种优良的第三方库和组件,用于解决各种开发问题和实现特定性能。同时,社区也提供了大量的技术文档、教程和解决方案,帮忙开发者解决问题和晋升技能程度。五、原生性能和用户体验React Native框架采纳原生渲染机制,能够间接调用设施的原生API,从而保障了利用的流畅性和响应速度。此外,React Native还反对原生模块集成,能够实现更好的用户体验和性能扩大。六、易学易用和开发效率相较于传统的原生开发,React Native采纳JavaScript语言进行开发,这使得学习曲线更加平缓。JavaScript语言易学易用,升高了开发门槛,同时React Native还提供了弱小的组件化开发模式和申明式UI设计,使得开发人员可能更疾速地实现业务逻辑和界面设计,进步了开发效率。总结一下,React Native框架的长处包含跨平台开发劣势、热更新和疾速迭代、丰盛的生态和社区反对、原生性能和用户体验、易学易用和开发效率等方面。这些长处使得React Native成为了泛滥开发者抉择的首选框架之一。心愿通过明天的分享,大家对React Native的特点和劣势有了更深刻的理解,如果你也对React Native感兴趣或者有更多想理解的内容,欢送留言给我,咱们一起探讨交换!感激大家的浏览,咱们下期再见!

February 22, 2024 · 1 min · jiezi

关于react-native:向React-Native应用添加屏幕捕捉功能

首发于公众号 前端混合开发,欢送关注。为用户启用屏幕截图性能曾经成为挪动利用中用户体验的重要局部。这项性能使用户可能保留或分享利用界面的以后状态,以记住一个难忘的时刻,与敌人分享成就,或向开发者报告问题。 在这篇文章中,咱们将摸索如何应用 react-native-view-shot 库在React Native利用中实现屏幕捕获。这个库简化了对特定视图或整个屏幕截图的过程。 在这个教程中,咱们将通过理论演示来展现这个库的性能。你能够在GitHub上查看咱们简略演示利用的残缺代码。 在React Native利用中应用屏幕捕获的用例在游戏利用中,提供屏幕截图性能能够让用户在社交媒体上与敌人分享他们的分数、实现的关卡和游戏内的成就。 在报告利用中的谬误或问题时,用户能够截取他们的屏幕,以显示他们遇到问题时或因为问题导致的利用以后状态。这能够帮忙利用维护者找到或复现问题。 用户还能够在电子商务利用、房地产利用或教育利用中截取诸如产品、房源或讲座幻灯片等内容的屏幕,与别人分享。 为什么应用 react-native-view-shot ?react-native-view-shot 无疑是实现React Native利用屏幕捕获性能的最佳保护库。它也高度可定制,因而你能够依据你的需要进行调整。 例如, react-native-record-screen 库记录用户的整个屏幕,而不是捕捉特定视图。同时, react-native-screenshot-detect 库检查用户是否应用他们的设施截图,但只实用于用React Native构建的iOS利用。 如果你想要截取某个视图或整个屏幕的快照,我举荐应用 react-native-view-shot 。然而,如果你想要录制整个屏幕,那么请应用 react-native-record-screen 。 装置 react-native-view-shot运行以下命令之一: //npm$ npm install react-native-view-shot --save//Yarn$ yarn add react-native-view-shot一旦装置实现,你须要构建一次利用。这是因为 react-native-view-shot 向利用增加了新的原生代码。 在构建实现并装置到你的设施上后,你能够开始在你的React Native利用中应用这个库来捕捉屏幕或视图。 应用 react-native-view-shot应用 react-native-view-shot 相当直接了当。咱们稍后会进行更具体的演示,但首先,让咱们看看这个库是如何工作的。 首先,从React和 react-native-view-shot 库中导入必要的组件: import ViewShot from 'react-native-view-shot`;import { useRef, useState } from "react";接下来,创立一个 viewShot 组件,并将其 useRef 设置为 null 。在此组件内渲染的任何内容都能够作为图像捕捉: 而后,咱们将创立一个状态来存储捕捉的图像的URI: const [uri, setUri] = useState("");当初创立一个函数来捕捉 viewShot 组件的内容,并将后果URI保留到状态中: ...

February 21, 2024 · 2 min · jiezi

关于react-native:在-React-Native-中原生实现动态导入

在React Native社区中,原生动静导入始终是期待已久的性能。在React Native 0.72 版本公布之前,只能通过第三方库和其余变通方法实现动静导入,例如应用 React.lazy() 和 Suspense 函数。当初,动静导入曾经成为React Native框架的原生局部。 在这篇文章中,咱们将比拟动态和动静导入,学习如何原生地解决动静导入,以及无效施行的最佳实际。 动态导入 vs. 动静导入在深入研究实现细节之前,了解什么是动静导入以及它们与动态导入有何不同是至关重要的,动态导入是在JavaScript中蕴含模块的更常见形式。 动态导入是你在文件顶部应用 import 或 require 语法申明的导入。这是因为在应用程序启动时,它们可能须要在你的整个应用程序中可用。 这是一个例子: import React from 'react';import {View, Text} from 'react-native';const MyComponent = require('./MyComponent');动态导入是同步的,意味着它们会阻塞主线程,直到模块齐全加载。这种行为可能导致应用程序启动工夫变慢,特地是在较大的应用程序中。然而,当一个库或模块在代码库的多个工夫或多个中央须要时,动态导入就会显得十分有用。 相比之下,动静导入赋予开发者在须要时即时导入模块的能力,引领了一个异步范式。这意味着代码是按需加载的。 总的来说,动态导入和动静导入的次要区别在于,动态导入在编译时解析,而动静导入在运行时解析。 在 React Native v0.72 版本之前,动静导入并不是开箱即用的反对,因为它们与 Metro 打包器不兼容,Metro 打包器负责在 React Native 应用程序中打包 JavaScript 代码和资产。 Metro 打包器不容许任何运行时更改,并通过移除未应用的模块并用动态援用替换它们来优化包大小。这意味着 React Native 开发者必须依赖第三方库或自定义解决方案来在他们的利用中实现动静导入。咱们将在本文前面探讨这些。 如何在React Native中原生实现动静导入要在 React Native中 应用原生动静导入,你须要装置0.72或更高版本的React Native。你能够通过在终端运行 npx react-native --version 来查看你的React Native版本。你还须要在你的我的项目中配置0.66或更高版本的Metro打包器。 React Native 中应用原生动静导入有两种形式:应用 import() 语法或应用 require.context() 办法。 ...

February 20, 2024 · 3 min · jiezi

关于react-native:React-Native推送通知完整的操作指南

首发于公众号 前端混合开发,欢送关注。推送告诉已成为构建挪动利用时须要思考的重要性能。因为它们相似于短信,但发送不须要任何费用,许多企业当初更喜爱应用推送告诉向利用用户发送信息和警报。 在这篇文章中,咱们将看到如何在React Native利用中创立和发送推送告诉。 什么是推送告诉?推送告诉是从应用程序发送到已装置该利用的用户的音讯或警报。次要有两种类型的告诉: 前台告诉:当应用程序正在关上并运行时发送给用户的告诉后盾告诉:无论应用程序是否以后关上,都会发送推送告诉在挪动利用开发世界中十分风行,起因有很多。例如: 使公司可能以较低的老本推广产品和优惠晋升整体用户体验能够更快地提供交易收据转化更多用户牢靠的,因为用户在关上手机时总是会收到离线音讯这些劣势使得推送告诉对简直所有类型的挪动利用都十分有用,从手机游戏到电商利用等等。 React Native 中的推送告诉架构在咱们深刻理解如何在 React Native 利用中实现推送告诉的技术细节之前,了解React Native推送告诉的工作原理可能会有所帮忙。这里有一个图表,简化了告诉服务如何与设施进行通信: 当波及到在React Native中设置推送告诉时,有几种设置形式: 原生平台特定的告诉服务(FCM/APNS)Expo推送告诉服务和其余云服务像Notifee这样的React Native库上面咱们更深刻地理解这些办法,而后深刻咱们的演示。 原生平台特定的告诉服务(FCM/APNs)Android和iOS平台都提供了用于接管推送告诉的原生平台特定API 实用于安卓设施的Firebase云消息传递(FCM)苹果推送告诉服务(APNs)实用于iOS设施咱们能够应用React Native Firebase库来在Android上集成FCM,应用 push-notification-ios 库来在iOS上集成APNs。 React Native Firebase 库也提供了一种通过 FCM 在iOS上发送推送告诉的办法。能够从Node.js服务器通过 firebase-admin 和 node-apn 向注册的挪动设施发送近程告诉 Expo推送告诉和其余云服务FCM 和 APNs 都是特定平台的原生推送告诉服务。如果咱们间接应用这些原生推送告诉服务,咱们通常须要在利用的前端和后端应用不同的库。 因为这可能会带来不便,因而有几个云服务提供了应用对立源代码同时解决FCM和APNs的办法。一些风行的推送告诉服务包含: Amazon Simple Notification Service (SNS)OneSignalAzure Notification Hubs Azure这些告诉服务在原生推送告诉零碎之上提供了一个形象层,通过一个托管的两头推送告诉服务器,正如你在之前显示的图表中看到的那样。 其余的React Native库,比方react-native-push-notification像 Notifee 和 react-native-notifications 这样的库提供了原生模块,能够通过对立的库API轻松接管近程告诉并显示本地告诉。 你能够间接应用 FCM/APNs 或者应用这些库的托管推送告诉服务。然而,请记住,咱们必须在 Expo 中应用裸工作流来应用这些库,因为这些库不蕴含在 Expo 应用程序中。 演示:如何在 React Native 中设置推送告诉要在React Native应用程序中应用推送告诉,咱们首先须要注册应用程序以获取推送告诉令牌。这个令牌是一个长字符串,能够惟一标识每个设施。而后,咱们将在服务器上的数据库中存储该令牌,发送告诉,并解决咱们发送的已接管到的告诉。 在咱们深入研究之前,咱们将向一个曾经开发的我的项目增加推送告诉。这个我的项目是一个用于发售二手物品的电子商务React Native应用程序。应用现有的我的项目将使咱们可能专一于咱们演示的推送告诉方面。 要将我的项目的源代码下载到你的电脑中,请在你的终端运行以下命令: ...

February 19, 2024 · 5 min · jiezi

关于react-native:ReactNative-安装环境问题

之前看一个评论说,开发多年的RN了,至今装置环境靠运气。的确难装,可算见识到了... warning: Insecure world writable dir /opt/homebrew/bin in PATH,mode 040777 我搜了良久,看到的都是这种答案 sudo chmod go-w /opt/homebrew/sbin 然而我的有效,也看了文件权限,也是失常的。。 最初有个大神说,sudo chmod -R go-w /opt/homebrew 这样就能够了。 得看本人的报错门路去批改权限,惊喜~~ 然而快乐没多久又遇到了新问题。 error /Library/Ruby/Site/2.6.0/rubygems.rb:264:in 'find_ spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException) 这个也是解决了良久,起初剖析是因为零碎的ruby 2.6.0 版本太低。于是就降级ruby,发现通过homebrew降级的 ruby 并没有笼罩胜利,包含批改 ~/.zshrc环境引入到homebrew装置的ruby也有效。 最终参考了这一篇文章,通过 rbenv批改 ruby版本。 第一步:首先装置 rbenv brew install rbenv第二步:须要在文件~/.zshrc中退出如下语句,否则rbenv无奈胜利批改零碎的ruby版本: export PATH="$HOME/.rbenv/bin:$PATH"eval "$(rbenv init -)"第三步:增加实现后,能够应用如下指令装置并应用ruby rbenv install 3.2.2rbenv global 3.2.3执行胜利后查看零碎默认版本 ruby --version刚开始未失效,而后重启终端,再次输入版本就能够了。Cloning into'/var/folders/*'fatal: unable to access "https://github. com/priteshrnandgaonkar/Flipper-Boost-i0SX.git/': HTTP/2 stream 1 was not closed cleanly before end of the underlying stream ...

August 29, 2023 · 1 min · jiezi

关于react-native:搭建-React-Native-的-Android-运行环境win11-版

咱们这个教程,次要是带着大家依照目前 React Native 官网最新的文档,来搭建 React Native 在 win11 中的运行环境。 一、装置 Node依照 RN 官网要求,须要先下载安装 Node.js。 如果不确定本人电脑中是否有装置过 Node,能够先执行第3步【查看 Node 版本】,如果能查看到 Node 版本,则阐明电脑中曾经装置过 Node。 1、下载 Node这里给大家提供一个 Node.js 的镜像下载地址,比 Node 官网下载速度快一些。 Node 镜像下载地址:https://registry.npmmirror.com/binary.html?path=node/因为 React Native 官网要求 Node 版本在 14 以上,所以咱们下载时留神抉择对应的 Node 版本。 咱们这个教程就以 Node v16.20 的版本为例,找到对应版本并下载: 2、装置 Node下载实现后,就间接双击安装包,而后【下一步】装置即可。 阐明:Node 能够装置在 C 盘以外的其余地位,然而留神 Node 的装置门路中不要呈现中文。 3、查看 Node 版本Node 装置胜利后,能够在终端中输入以下命令,查看目前装置的最新的 Node 版本号: node -v

June 5, 2023 · 1 min · jiezi

关于react-native:React-Native开发初体验

环境装置参见官网: https://reactnative.dev/docs/environment-setup https://reactnative.cn/docs/environment-setup Notes: 针对依赖Node外围的包,RN没有进行解决,须要借助rn-nodeify解决,e.g. https://github.com/mvayngrib/react-native-crypto针对Java依赖的版本问题,能够借助jetifier主动解决大部分的版本差别针对Java依赖版本问题,能够通过patch-package打补丁 打出的补丁会蕴含很多无用的局部,能够选择性删除打出的补丁可能二次批改,e.g.https://github.com/browserify/pbkdf2/blob/master/lib/default-encoding.js 源码中global.process && global.process.version,装置后global.process && global."v16.13.0",patches/pbkdf2+3.1.2.patch须要二次批改我的项目创立npx react-native@latest init rnProject Notes:项目名称只反对驼峰,不反对连字符。 我的项目运行npm run android 往模拟器或真机装置APK:包运行所须要的资源。援用原生依赖,须要从新运行该命令。--mode=release长期打包,输入门路android\app\build\outputs\apk\releasenpm run start 运行Metro打包JS代码,启动热更新,在模拟器或真机实时查看改变。--reset-cache革除Metro缓存,从新编译JS代码。革除运行缓存"./gradlew" clean 切换到android目录下,在命令行执行该命令,可革除gradle缓存。npx react-native start --reset-cache 革除Metro缓存,从新编译JS代码利用场景:环境报错、开发者工具呈现问题页面适配计划一: // src/utils/px2dp.jsimport { Dimensions, PixelRatio, StyleSheet } from 'react-native';const windowWidth = Dimensions.get('window').width;const px2dp = function (px) { if (!isNaN(px)) { return (windowWidth / 1080) * px / PixelRatio.get() } else { return 0 }}export default px2dp// entry.jsimport px2dp from '../utils/px2dp';StyleSheet.create({ pageTitle: { fontSize: px2dp(64), lineHeight: px2dp(85), paddingLeft: px2dp(100), paddingRight: px2dp(100), marginTop: px2dp(80), },})计划二: ...

June 1, 2023 · 3 min · jiezi

关于react-native:2023-年了React-Native-中怎么画图表

作者:iambool 前言平时写图表相干需要,用得最多的图表库就是echarts。echarts 在 web 端的体现曾经相当成熟,官网对小程序端也提供了解决方案,而在 RN 方面却没有相应反对。市面上搜到的,大多实质还是基于 webview 实现,而我更偏向于基于 RN 的计划,毕竟原生的体验会比 Web 的更好一些。 所以咱们公布了@wuba/react-native-echarts 来满足需要。对实现原理感兴趣的能够看这里 接下来我将应用 @wuba/react-native-echarts来做一个理论我的项目中的利用,截图如下: 小提示如果你曾经有 APP 包,能够疏忽后面的打包流程,间接跳到第 4 步。试用的残缺代码放在 github 上了,地址:https://github.com/iambool/TestApp具体应用过程如下1、开发环境搭建本地搭好 RN 开发环境,搭建过程网上一抓一大把,就不赘述了。 2、筹备 RN 工程因为是试用,所以我用 expo 新初始化了一个 rn 工程,叫 TestApp。 npx create-expo-app TestApp 3、build App 包用命令行生成包 ios android app 包。这里 ios 倡议用模拟器(不须要配证书),安卓我是连的真机 yarn androidyarn ios生成包后,手机看到曾经装置了这个利用,就代表胜利啦。 4、 装置相干依赖yarn add @wuba/react-native-echarts echartsyarn add @shopify/react-native-skiayarn add react-native-svg留神,如果你是在已有工程中装置,装置实现后要从新打个新包,不然短少原生依赖会报错; 5、试用 Skia 模式@wuba/react-native-echarts 反对两种渲染模式(Skia 和 Svg),先用 Skia 试一个简略的图表。大抵分为这几个小步骤: 引入 echarts、图表组件等依赖注册图表组件创立图表实例,并设置图表的配置(option)页面销毁时要记得同步销毁图表实例具体代码如下: ...

March 15, 2023 · 4 min · jiezi

关于react-native:React-Native-071正式版发布Ts成为默认开发语言

2023年1月14日,React Native官网公布了0.71版本,此版本带来了很多重磅和突破性的更新,同时,感激70多位贡献者带来的了1000屡次提交。上面是0.71版本带来的次要更新内容: 默认开发语言为TypeScript应用Flexbox Gap使布局更加简略开发者体验晋升无关新架构内容的降级引入的局部web开发规范的属性,款式及事件复原PropTypes其余更新TypeScript成为默认开发语言从0.71版本开始,咱们将React Native的默认开发语言从JavaScript变成TypeScript,在新建的我的项目的时候会有所体现,与此同时我的项目根目录会减少一个tsconfig.json文件用于辅助开发者编写语法正确的Ts代码。另外0.71版本因自身已反对ts,所以不须要再package.json文件中增加@types/react-native依赖。 无关TypeScript,咱们能够将它了解为是增强版JavaScript。TypeScript 由微软开发的自在和开源的编程语言,是 JavaScript 的一个超集,反对 ECMAScript 6 规范(ES6 教程)。TypeScript 设计的初衷就是为了应答大型利用开发,它能够编译成纯 JavaScript,最终运行在浏览器环境中。 Flexbox Gap让布局更加简略此版本引入了web开发规范的属性gap、rowGap、columnGap,应用这些属性能够很不便的设置组件距离。并且,在将来的版本中,咱们还会减少百分比布局。那gap、rowGap、columnGap属性到底有什么用呢?比方设置组件之间距离为margin: 10,其成果如下图。 margin的作用就是用在所有子元素的外边缘,并且在Flexbox布局中下不会生效,次要用于设置元素内部的间距。同时,咱们还能够通过设置非平均边距、在父元素上应用负边距等来使得布局开发变得更加容易。 比方,应用gap属性,咱们还能够在容器上设置gap: 10来实现卡片外部边距,如下图所示: 如果想要理解更多Flexbox gaps的内容,能够参考 blogpost from CSS Tricks。 Web属性反对此版本增加了很多Web属性的反对,使得React Native的api和Web平保持一致,比方 accessibility, behavior和style props等。这些新属性都是是附加的,因而对于等效的可拜访性、行为或款式,不会呈现什么异样影响,比方Image和TextInput组件。 Accessibility比方,咱们引入ARIA属性作为React Native的根底属性。事实上,这些属性存在咱们简直所有的React Native组件中,比方aria-label, aria-labelledby,aria-modal, id, aria-busy, aria-checked, aria-disabled, aria-expanded, aria-selected, aria-valuemax, aria-valuemin, aria-valuenow, and aria-valuetext。 并且,咱们行将在将来的版本中引入其余一些行为属性,比方aria-hidden, aria-live, role和 tabIndex等。如果想要理解更多对于Accessibility的内容,能够关上Web Props umbrella issue。 Specific Behavior将来,为了对齐Web规范,咱们还会再根底组件中引入更多的可拜访性、行为或款式等属性,比方Image和TextInput组件。 Image: alt, tintColor, crossOrigin, height, referrerPolicy, src, srcSet, and width.TextInput: autoComplete, enterKeyHint, inputMode, readOnly, and rows.Styles为了与Web平台的css款式保持一致,咱们在React Native中增加了如下的款式反对。 ...

January 18, 2023 · 1 min · jiezi

关于react-native:ReactNative071正式版发布Ts作为首要开发语言

时隔近4个月的工夫,ReactNative带来了0.71版本的更新,这速度比照隔壁Flutter不得不说是真的有的慢。 这个版本的更新的内容还是比拟重磅和突破性的,次要体现在如下几点: 编程语法默认改为TypeScript应用Flexbox Gap使布局更加简略开发者体验晋升无关新架构内容的降级引入的局部web开发规范的属性,款式及事件复原PropTypes其余变动默认TypeScript从0.71版本开始,新建的我的项目的开发语言默认从JavaScript变成TypeScript,与此同时我的项目根目录会减少一个tsconfig.json文件用于辅助开发者编写语法正确的Ts代码。另外0.71版本因自身已反对ts,所以不须要再package.json文件中增加@types/react-native依赖。 无关TypeScript,能够了解为增强版JavaScript. TypeScript 是 JavaScript 的一个超集,反对 ECMAScript 6 规范(ES6 教程)。TypeScript 由微软开发的自在和开源的编程语言。TypeScript 设计指标是开发大型利用,它能够编译成纯 JavaScript,编译进去的 JavaScript 能够运行在任何浏览器上。应用Flexbox Gap让布局更加简略此版本引入了web开发规范的属性gap, rowGap, columnGap,应用这些属性能够更加不便且实用的进行组件之间隔的设置。比方设置组件之间距离为margin: 10,成果如下应用gap: 10,成果如下,更简略也更合乎预期 开发者体验晋升React DevTools开发调试工具减少了两个比拟好用的性能,点击元素检查和组件高亮, 这对于咱们开发中调试布局页面来说更加敌对,也更加容易让咱们定位组件元素。 Hermes在0.71版本中对Hermes引擎做了进一步的降级,包含并不限于如下: JSON.parse性能晋升30%减少对String, TypedArray, and Array属性at()的反对在Metro中通过网络实现加载source maps新架构的降级0.71版本带来了诸多对于新架构体验及性能方面的降级。 大幅度缩小了Android平台的编译工夫,并解决了诸多Window平台的编译问题当初能够启用新体系结构,而无需在应用程序中增加任何C++代码,并且CLI应用程序模板已革除所有C++代码和CMake文件。在iOS平台设置开启新架构反对更加简介在iOS平台,在podspec中新增了install_module_dependencies函数用于治理所有须要的依赖项。引入局部web开发规范的内容该版本蕴含了许多web规范货色,以在许多平台上对其React Native的API。这些新属性都是是附加的,因而对于等效的可拜访性、行为或款式道具,不会呈现预期的影响,比方Image和TextInput组件。 Image: alt, tintColor, crossOrigin, height, referrerPolicy, src, srcSet, and width.TextInput: autoComplete, enterKeyHint, inputMode, readOnly, and rows.其余变动移除了AsyncStorage和MaskedViewIOSJSCRuntime挪动至react-jsc,如果须要JSCRuntime,须要增加react-jsc依赖。总结以上就是0.71版本的次要更新内容,此次重点还是把TypeScript作为首要开发语言。

January 14, 2023 · 1 min · jiezi

关于react-native:ReactNative支付密码输入框

我的项目中需要如果波及钱包,领取等性能,能够大概率会用到输出明码组件,也算是个常见组件吧。 之前写过一个纯js的开源组件,应用的类的模式,也比拟老了,可间接增加npm库到我的项目中进行应用。 最近我的项目须要,又从新写了一个hooks版本的,当初间接上源码,对于不想增加依赖库的搭档,可间接复制源码到我的项目中,间接应用。 'use strict';import React, {useRef, useState} from 'react';import {StyleSheet, View, Pressable, TextInput} from 'react-native';// 领取明码输入框const PasswordInput = ({isAutoFocus = false}) => { const [msg, setMsg] = useState(''); const textInputRef = useRef(); const onEnd = (text: string) => { console.log('输出明码:', text); }; const _getInputItem = () => { let inputItem = []; for (let i = 0; i < 6; i++) { inputItem.push( <View key={i} style={i === 5 ? [styles.textInputView, {borderRightWidth: 1}] : [styles.textInputView, {borderRightWidth: 0}]}> {i < msg.length ? <View style={{width: 16, height: 16, backgroundColor: '#222', borderRadius: 8}} /> : null} </View>, ); } return inputItem; }; const _onPress = () => { textInputRef?.current.focus(); }; return ( <Pressable onPress={_onPress}> <View style={styles.container}> <View style={{flexDirection: 'row', marginTop: 36, justifyContent: 'center'}}> <TextInput style={styles.textInputMsg} ref={textInputRef} maxLength={6} autoFocus={isAutoFocus} keyboardType="number-pad" defaultValue={msg} onChangeText={text => { setMsg(text); if (text.length === 6) { onEnd(text); } }} /> {_getInputItem()} </View> </View> </Pressable> );};const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#ffffff', justifyContent: 'center', alignItems: 'center', }, textInputView: { height: 85 / 2, width: 85 / 2, borderWidth: 1, borderColor: '#c9c7c7', justifyContent: 'center', alignItems: 'center', }, textInputMsg: { height: 45, zIndex: 99, position: 'absolute', width: 45 * 6, opacity: 0, },});export default PasswordInput;应用形式就很简略了: ...

November 27, 2022 · 1 min · jiezi

关于react-native:Native-Wechat-React-Native-微信-SDK

Native Wechat在 Android 与 iOS 反对微信 SDK 的 React Native 库。 动机许多 React Native 开发者不具备原生开发能力,更不必提将他们的 App 对接到微信。尤其微信 OpenSDK 是一个令人头疼的货色,因为它的文档非常蹩脚,外面许多的 API 并不清晰与直观。为帮忙应用 React Native 的开发者对接微信,我开发了这个库,心愿可能帮忙到您。 个性Native WeChat 是新的,与此同时许多同类的库都暂停保护并不再适配最新的微信 API;Native WeChat 反对新旧 React Native 架构;Native Wechat 反对 TurboModule,能够懒加载以放慢 App 启动;反对 TypeScript 以获取更好的语言提醒与类型谬误检测;简直所有的 API 均返回 Promise。应用入门注册 SDK在调用任何 API 之前,请务必调用 registerApp 来注册 SDK。 import {registerApp} from 'native-wechat';useEffect(()=>{ return registerApp('wx964290141ebe9b7b');}, [])当调用 registerApp 后,它将注册一个从原生端返回事件的监听器,并返回一个函数用于登记这个监听器。 调用 API是时候调用 API 了。举个例子,咱们要向微信发送一个鉴权申请,并承受返回的 code,您须要调用 sendAuthRequest。 import {registerApp, sendAuthRequest} from 'native-wechat';import {Button, Text} from 'react-native';import {verifyWechatCode} from '@/api/auth/wechat'useEffect(()=>{ registerApp('wx964290141ebe9b7b');}, [])const onButtonClicked = async () =>{ const {data: {code}} = await sendAuthRequest(); await verifyWechatCode(code);}return <Button onClick={onButtonClicked}> <Text>Send Auth Request</Text></Button>简直所有 API 都会返回 Promise,sendAuthRequest 也是。当用户在微信上受权信息后,Promise 将变为 resolved,并携带 code。所有返回 Promise 的 API 都返回一个名为 NativeWechatResponse 的泛型类型。 ...

November 6, 2022 · 1 min · jiezi

关于react-native:reactnative之路径别名配置

1. 初始化我的项目创立我的项目应用 react-native 脚手架创立一个名字叫 rn-demo 的我的项目,应用官网 typescript 模板。 npx react-native init rn_demo --template react-native-template-typescript留神:项目名称不能应用 - 字符,脚手架不反对。运行我的项目yarn ios或者 yarn android创立文件如下图所示: 接下来要给src/utils门路配置别名。 2. 编辑 tsconfig.json 设置别名用来给 .ts 和 .tsx 引入文件的时候解析门路别名应用。 { "extends": "@tsconfig/react-native/tsconfig.json", /* Recommended React Native TSConfig base */ "compilerOptions": { /* Visit https://aka.ms/tsconfig.json to read more about this file */ /* Completeness */ "skipLibCheck": true, /* Skip type checking all .d.ts files. */ /* 配置根底地址 */ "baseUrl": ".", /* 配置门路别名 */ "paths": { "*": ["src/*"], } }}3. 退出babel插件babel-plugin-module-resolver用于babel打包的时候解析门路别名应用,不配置的话,运行过程中会报错,找不到文件。 ...

August 27, 2022 · 1 min · jiezi

关于react-native:react-native环境安装M1-iOS安装

记录M1装置react native。 必须装置的依赖有:Node、yarn、Watchman、Xcode 和 CocoaPods。 装置步骤装置node,v14以上,查看官网教程;装置yarn,npm install -g yarn;装置watchman,M1没有brew命令,先装置brew工具; 输出以下命令,如不胜利,用root权限 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"查看是否装置胜利 brew --version 装置watchman,输出以下命令 brew install watchman装置Xcode,v12以上,能够通过 App Store 或是到Apple 开发者官网上下载; 装置CocoaPods,M1举荐应用以下装置形式 brew install cocoapods创立我的项目 npx react-native init AwesomeProjectcd AwesomeProjectyarn ios会看到iOS虚构器启动胜利 装置过程的问题一:在执行brew install watchmanError: Command failed with exit 128: git输出brew -v别离执行这2条命令,再次输出 brew install watchman

August 26, 2022 · 1 min · jiezi

关于react-native:用-React-结合-SAP-UI5-Web-Components-来开发-SAP-Fiori-应用

在 Fiori Fundamentals 和 SAP UI5 Web Component 诞生之前,SAP UI5 是开发SAP Fiori利用惟一可供选择的前端框架。 很显然SAP对前端畛域蓬勃发展的Vue,Angular,React这三驾马车并未熟视无睹,这才有了Fiori Fundamentals和SAP UI5 Web Component的问世。 什么是 Web Components?Web Components 是浏览器内置的 UI 元素框架。 它具备 0kB 的占用空间,并且截至明天在所有次要浏览器中都可用。 Web 组件通过封装内容 (HTML)、示意 (CSS) 和行为 (JS) 的自定义 HTML 标记来加强浏览器的规范词汇。 Web 组件构建在以下 Web 平台 API 之上:自定义元素、Shadow DOM、ES 模块和 HTML 模板。 因为 Web 组件依赖于所有古代浏览器的 Web 规范反对,它们的益处是能够与大多数开箱即用的基于 HTML 的 Web UI 框架一起工作, 当然也就包含了 SAP UI5. 什么是 SAP UI5 Web Components?UI5 网页组件UI5 Web Components 在原生 API 之上增加了 enterprise-flavored sugar,即对企业级前端利用开发的反对。 ...

July 22, 2022 · 1 min · jiezi

关于react-native:React-NativeScrollView横向滚动的嵌套

如果你须要实现相似的成果,在程度滚动<ScrollView>标签中持续嵌套程度滚动的<ScrollView>标签,你会发现在Android中子ScrollView没方法失常滑动。具体能够参考这个issue。效果图如下: 解决方案:应用react-native-gesture-handler这个npm库的ScrollView组件代替原生组件。

July 10, 2022 · 1 min · jiezi

关于react-native:React-Native安装记录20220624

for React Native v0.69时过境迁,包含官网的装置指引都跟不上时代变动啊,折腾半天反正是能够了,记下来心愿能够帮忙到他人。 环境Windows 10 64位家庭版手机模拟器 夜神Node node -v v16.13.1 (官网要求不低于14)JavaSDK javac --version v11.0.7 (官网要求不低于11)Android Studio Android Studio Chipmunk | 2021.2.1 (这个是本次新装的,凭本人感觉装吧,两头会提醒被墙,我没高效上网,跳过)装置之后看了很多他人的装置教训,最初什么也没做,只把环境变量注册了。(留神启用Android Studio,点击自定义->全副设置,外观和行为->零碎设置->安卓SDK,复制一下本地SDK装置门路(如果你晓得SDK目录能够不必干这个)。回到操作系统,增加零碎环境变量ANDROID_HOME,值就是方才复制的SDK目录。编辑零碎环境变量PATH,增加以下四项: %ANDROID_HOME%\platform-tools%ANDROID_HOME%\emulator%ANDROID_HOME%\tools%ANDROID_HOME%\tools\bin如果还开着命令行工具的话关掉它(不然大概率不会本人重载环境变量的更新),筹备工作实现。 初始化Native我的项目确认没有装置过react-native-cli,装过请卸载。进入本人的工作目录执行npx react-native init AwesomeProject就好了,会主动创立AwesomeProject目录。 执行yarn react-native run-android会生成一个apk,位于我的项目门路下的android/app/build/outputs/apk/debug/app-debug.apk。执行过程中会报错,因为没开模拟器。 看一下本人的ip,通常我的项目会默认在8081端口。运行夜神模拟器,把下面的apk拖进模拟器,装置后运行报错,此时点菜单中的更多(...图标),再点击弹出菜单中的菜单(三横线图标)关上配置项,将开发设置中的服务端地址里写上本人的ip和端口。从新关上夜神,再次运行app。失常关上了。 装置TypeScriptyarn add tslib @types/react @types/react-nativeyarn add --dev react-native-typescript-transformer typescript从已有的react我的项目的根目录复制tsconfig.json。在根目录新建rn-cli.config.js,内容为: module.exports = { getTransformModulePath() { return require.resolve('react-native-typescript-transformer'); }, getSourceExts() { return ['ts', 'tsx']; },};将App.js更名为App.tsx,感觉好多了。再次启动服务 npx react-native start。 懒人不贴图,文章完结。

June 24, 2022 · 1 min · jiezi

关于react-native:React-Native如何做性能优化

和原生开发相比,React Native 最显著的有余就是页面的渲染速度,比方页面加载慢,渲染的效率低等。对于这些问题,都是开发中常见的问题,也是应用React Native 开发跨平台利用时必须优化的点,由此引入一个问题,React Native的性能优化到底应该如何做? 置信对于这个问题,大多数人第一眼看到后都是很懵逼的。因为大多数人除了业务开发之外,对于React Native原理性的货色都理解甚少。其实,通过咱们多年的教训,一个未经优化的 React Native 利用,从大体上讲能够分为 3 个瓶颈: 当然,RN的性能优化包含JavaScript 侧和原生容器的优化。不过,咱们明天咱们次要站从客户端角度进行优化。 一、React Native 环境预创立在 最新的React Native 架构中,Turbo Module (新架构下的通信形式)是按需加载,而旧框架则是在初始化的时候把Native Modules一股脑的加载进来,同时 Hermes 引擎放弃了 JIT,在启动速度方面也有显著晋升。如果对React Native新架构感兴趣的同学,能够参考:React Native新架构。 抛开这两个版本在框架方面的优化,在启动速度方面,咱们还能做些什么呢?首先,咱们看一下React Native 环境预创立。在混合工程中,React Native 环境与加载页面的关系如下图。 从上图中能够看到,在混合利用中,独立的 React Native 载体页都有本人独立的执行环境。Native 域包含 React View、Native Modules;JavaScript 域泽包含 JavaScript 引擎、JS Modules、业务代码;两头通信应用的是Bridge/JSI(新版本)。 当然,业内也有多个页面复用一个引擎的优化。然而多页面复用一个引擎存在一些问题,比方 JavaScript 上下文隔离、多页面渲染错乱、JavaScript 引擎不可逆异样等。而且复用的性能不稳固,思考到投入产出比、保护老本等方面,通常在混合开发中,采纳的是一个载体页一个引擎。 通常,一个 React Native 页面从加载渲染到展现大抵分为以下几步:【React Native 环境初始化】 -> 【下载/加载 bundle】 -> 【执行JavaScript 代码】。 环境初始化这一步次要蕴含的工作包含:创立 JavaScript 引擎、Bridge、加载 Native Modules(旧版)。依据咱们的测试,初始化这一步在 Android 环境中是特地耗时的。所以,咱们想到的第一个优化点就是提前将 React Native 环境创立好,流程如下。 ...

June 17, 2022 · 4 min · jiezi

关于react-native:Metro拆包工作原理与实战

一、背景触过RN的同学都晓得,热更新作为RN最大的特点之一,能够让开发者随时上线新的迭代以及修复线上Bug。在上一篇文章咱们聊了一下热更新平台搭建,明天来咱们聊聊热更新中的拆包环节。 热更新和拆包都是大家聊得比拟多的话题,通常一个聊得比拟多的技术话题都会有一套成熟的技术计划,比方热更新平台就有 CodePush 这样的成熟计划,但拆包却没有一套大家都公认成熟的计划。不过,市面上反对拆包的计划有react-native-multibundler、携程的moles-packer 还有58同城的metro-code-split,因为前两种曾经进行更新,所以不做特地的介绍。 家喻户晓,Facebook 开源的 Metro 打包工具,自身并没有拆包性能,它的次要性能是将 JavaScript 代码打包成一个 Bundle 文件,而且 Metro 也不反对第三方插件,所以社区也没有第三方拆包插件。 不过,咱们在浏览 Metro 源码的时候,发现了一个可配置的函数 customSerializer,从而找到了不入侵 Metro 源码,通过配置的形式给 Metro 写第三方插件的办法。有了 Metro 的 customSerializer 办法后,当初咱们也能够给 Metro 来写插件了,通过插件来提供独自拆包能力。 二、metro-code-split根本应用metro-code-split是58同城技术团队开发的反对RN拆包的插件,目前反对最新的0.66.2版本,相干的文章介绍能够参考:58RN 页面秒开计划与实际 接下来,咱们看一下如何在现有的我的项目中接入metro-code-split。首先,咱们在我的项目中装置metro-code-split插件。 npm i metro-code-split -D//或者yarn add metro-code-split -D而后,在package.json配置文件中增加如下脚本: "scripts": { "start": "mcs-scripts start -p 8081", "build:dllJson": "mcs-scripts build -t dllJson -od public/dll", "build:dll": "mcs-scripts build -t dll -od public/dll", "build": "mcs-scripts build -t busine -e index.js" }脚本的具体含意如下: ...

June 6, 2022 · 4 min · jiezi

关于react-native:React-Native-资源更新增量包的优化实践

本文首发于微信公众号“Shopee技术团队” 。 作者:Pei,来自 Shopee 商家服务前端团队。 1. 背景Shopee 的许多手机利用是原生与 React Native(下文简称 “RN”)的混合(hybrid)利用。在用户关上 App 时,客户端会发动申请查看是否有新版 RN 资源。若有,则后盾静默下载最新资源,从新加载 RN,以实现 RN 更新。这样的更新过程免却了用户去 Google Play/App Store 从新下载 App 的麻烦,也能迅速把最新资源推送给所有用户。 另一方面,RN 资源虽会更新迭代,但新旧版的差别其实只占小局部,让用户下载全量资源不仅节约用户流量,也影响用户对 App 的应用体验(因为后盾静默更新依然会挤占带宽资源)。 自然而然,咱们会想到“增量(差量)更新”,客户端仅下载新旧 RN 资源的差别局部。这个差别局部汇总到一个文件里,这个文件被称之为增量包(或补丁包)。下载实现并验证补丁包的合法性后,方可与旧版本合并为新版本,以此节约流量。 思考到 Shopee 次要市场的网络条件,数据流量的节约尤为重要。但这个增量包应该是怎么的呢?本文会以循序渐进的思路剖析各种计划的优缺点,包含 Shopee 公司内的摸索实际过程所产生的计划,以及业界提供的计划,最初提出 FolderBsdp 算法,对间接资源进行差分,实现增量更新。 2. 增量包实际计划进化之路2.1 间接传输差别的(原始)文件RN 资源包含转译后的 JavaScript 代码、各语言翻译 JSON 文件、图片等媒体资源、配置文件。咱们把这些资源称为“间接资源”。它们是 RN 打包的间接产物,也是日常供客户端调用的存在模式。如果这些“间接资源(原始文件)”在 CDN 上,保留新旧资源的文件目录,即可对应下载新增的和批改的文件。 其毛病次要有两方面: 1)扩散传输易出错如果有新增图片和批改翻译文件等批改,须要发动屡次 HTTP 申请到 CDN 下载文件,这样会复杂化更新的异样解决状况,比方局部文件下载过程中断的复原问题。 2)传输量大费流量图片和翻译 JSON 文件用原始文件传输节约数据流量,因为这些资源本能够被压缩。翻译文件体积较大,但每个版本的批改个别是轻微新增若干行,没有必要直传整个文件。因而,所谓传输“差别”的局部,文件级别的“差别”颗粒度还是太大了。 2.2 文件间的差分算法 BSDiff为了防止 2.1 中的问题,咱们引入了差分算法,以实现增量更新。 2.2.1 差分算法文件间的差分算法是一种实现增量更新的办法。差分算法的入参是新旧两个文件,其输入是两个文件的差别局部,称为 Patch,即补丁包(也称增量包)。 一个差分算法还有与之配套的打补丁算法,其入参是旧文件和 Patch,输入是新文件。不同的差分算法各有优劣,体现在差分和打补丁操作的时空复杂度、Patch 体积、Patch 内容可读性等。 ...

June 4, 2022 · 3 min · jiezi

关于react-native:ReactNative使用总结

记录学习 RN 的文档,比拟随便搭建开发环境基本上依照官网的文档一步步来即可,留神须要迷信上网 搭建开发环境请不要应用一些移植的终端环境,例如 git bash 或 mingw 等等,这些在 windows 下可能导致找不到环境变量。请应用零碎自带的命令行(CMD 或 powershell)运行。创立我的项目npx react-native init AwesomeProject --version X.XX.Xversion 指定版本 0.67.4 版本须要 JDK1.8 0.68 当前版本须要 JDK11 手机投屏工具scrcpy手机投屏工具,不便间接在电脑观看成果,毛病是须要数据线连贯 Flex所有的容器默认布局都是 Flexflex-direction: column(默认)RN 中款式无奈继承, (补充: React Native 实际上还是有一部分款式继承的实现,不过仅限于文本标签的子树。)单位数值, 单位是dp,无奈应用 px,vw,vh 等百分比PPI(DPI)大多数情况下这两种是相等的,即 PPI = DPI。PPI 是屏幕像素与设施的比值:PPI =屏幕对角线像素点/屏幕对角线物理宽度。DPI(dots per inch)打印精度 (每英寸所能打印的点数)字体dp(dip)(Density-independent pixels)一种基于屏幕密度的形象单位。在每英寸 160 点的显示器上,1dp = 1px。特地须要留神 dp 是绝对长度单位,简略的说 1dp 在不一样的屏幕或者不一样的 ppi 下展示进去的“物理长度”可能不统一。px 像素点。也是绝对长度in(inch)英寸。物理长度Transformtransform 属性值接管的是数组 <View style={ { transform: [{ scaleY: 2 }], }, }> <Text>ScaleY by 2</Text></View>ViewView 是一个反对 Flexbox 布局、款式、触摸响应、和一些无障碍性能的容器。不反对设置字体款式不能间接绑定点击事件(应用TouchableOpacity)Text一个用于显示文本的 React 组件,并且它也反对嵌套、款式,以及触摸解决。留神: <Text>元素在布局上不同于其它组件:在 Text 外部的元素不再应用 flexbox 布局,而是采纳文本布局。这意味着<Text>外部的元素不再是一个个矩形,而可能会在行末进行折叠。 ...

May 4, 2022 · 2 min · jiezi

关于react-native:React-Native-高德地图定位-hooks

装置yarn add react-native-amap-geolocation应用 const {coords} = useLocation() console.log('ccc', coords) // 以后地位,非实时 const {location} = useLocation('watch') console.log('l333', location.city) // 实时定位useLocation.tsimport React, {useCallback, useEffect, useState} from "react"import { PermissionsAndroid } from "react-native"import { init, Geolocation } from "react-native-amap-geolocation"import {AMAP_ANDROID_KEY} from '@/constants/constants'interface Position { coords: { /** 精度 米 */ accuracy: number altitude?: number heading: number latitude: number longitude: number speed: number } location?: any}interface PositionWatch { coords: { /** 精度 米 */ accuracy: number altitude?: number heading: number latitude: number longitude: number speed: number } location: { accuracy: number adCode: string address: string // "重庆市九龙坡区科城支路85号凑近重庆市九龙坡区人力资源和社会保障综合服务中心", altitude: number city: string // "重庆市", cityCode: string // "023", coordinateType: string // "GCJ02", country: string // "中国", description: string // "在重庆市九龙坡区人力资源和社会保障综合服务中心左近", district: string // "九龙坡区", errorCode: number // 0, errorInfo: string // "success", gpsAccuracy: number // -1, heading: number // 0, latitude: number // 29.512879, locationType: number // 2, longitude: number // 106.458555, poiName: string // "重庆市九龙坡区人力资源和社会保障综合服务中心", province: string // "重庆市", speed: number // 0, street: string // "科城支路", streetNumber: string // "85号", timestamp: number // 1651214072119, trustedLevel: number // 1 } timestamp: number }type TLocType = 'watch'function useLocation (): Positionfunction useLocation (locType: TLocType): PositionWatchfunction useLocation (locType?: TLocType): Position | PositionWatch { const [position, setPosition] = useState<Position>({ coords: { latitude: 0, longitude: 0, accuracy: 0, heading: 0, speed: 0, }, location: {} }) /** 初始化 */ const initAMap = useCallback(async () => { await PermissionsAndroid.requestMultiple([ PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION, ]); await init({ ios: '', android: AMAP_ANDROID_KEY }) }, []) /** 获取以后地位 */ const getPosition = useCallback<() => Promise<Position>>(() => { return new Promise((resolve, reject) => { Geolocation.getCurrentPosition(({ coords }) => { resolve({coords: coords}) }, err => { reject(err) }) }) }, []) useEffect(() => { let wid async function init() { await initAMap() if(locType === 'watch'){ wid = Geolocation.watchPosition((curPosition) => { setPosition({...curPosition}) }, (err) => { console.log('实时定位出错:', err) Geolocation.clearWatch(wid) }) }else{ const curPos = await getPosition() setPosition({...curPos, location: {}}) } } init() return () => { locType === 'watch' && Geolocation.clearWatch(wid) } }, [initAMap, getPosition, locType]) return position}export default useLocation

April 29, 2022 · 2 min · jiezi

关于react-native:reactnative-设置环境变量-reactnativedotenv

场景有时候咱们须要设置一些环境变量,这里有很多形式。例如:通过特定的标识判断以后是什么环境,再动静读取对应的变量。那么如何通过编译命令设置环境变量呢?咱们能够理解一下 react-native-dotenv。 实现形式1.装置react-native-dotenvnpm install react-native-dotenv2.在你的.babelrc(如果没有新建一个)文件中配置一下设置简略配置,都应用默认参数{ "plugins": [ ["module:react-native-dotenv"] ]}定制配置,自定义{ "plugins": [ ["module:react-native-dotenv", { "envName": "APP_ENV", "moduleName": "@env", "path": ".env", "blocklist": null, "allowlist": null, "blacklist": null, // DEPRECATED "whitelist": null, // DEPRECATED "safe": false, "allowUndefined": true, "verbose": false }] ]}3.在我的项目根目录下新建.env文件,外面能够配置须要的变量,应用key=value的模式eg: APP_TRYPE = ZZZAPP_NAME = AAA4.应用import {APP_TRYPE, APP_NAME} from "@env"console.log('APP_TRYPE:',APP_TRYPE)输入:APP_TRYPE:ZZZconsole.log('APP_NAME',APP_NAME)输入:APP_NAME:AAA如果有多种配置,如果在编译的时候指定应用哪个呢?1.设置package.json// package.json{ "scripts": { "start:wx": "MY_ENV=wx npx react-native start", "start:ali": "MY_ENV=ali npx react-native start", }}2.定义envName为了能应用下面的MY_ENV,须要咱们从新定义envName { "plugins": [ ["module:react-native-dotenv", { "envName": "MY_ENV" //这里须要设置为下面package.json对应的 }] ]}运行package.json的命令的时候,读取的环境变量文件就是.env.ali,.env.wx ...

April 27, 2022 · 1 min · jiezi

关于react-native:reactnative-TextInput-无法自动失去焦点需要点击多次切换到其他组件

场景形容比拟常见的需要是有个输入框,旁边有个搜寻按钮或者发送按钮。点击输入框的时候会唤起虚构键盘,输出文字点击旁边的按钮或者切换其余组件,点击第一次是收起键盘,无奈触发点击事件,须要再点击一次。 解决方案1.首先认识一下:keyboardShouldPersistTaps官网形容keyboardShouldPersistTaps如果以后界面有软键盘,那么点击 scrollview 后是否收起键盘,取决于本属性的设置。(译注:很多人反馈 TextInput 无奈主动失去焦点/须要点击屡次切换到其余组件等等问题,其要害都是须要将 TextInput 放到 ScrollView 中再设置本属性) 'never' (默认值),点击 TextInput 以外的子组件会使以后的软键盘收起。此时子元素不会收到点击事件。'always',键盘不会主动收起,ScrollView 也不会捕获点击事件,但子组件能够捕捉。'handled',当点击事件被子组件捕捉时,键盘不会主动收起。这样切换 TextInput 时键盘能够放弃状态。少数带有 TextInput 的状况下你应该抉择此项。false,已过期,请应用'never'代替。true,已过期,请应用'always'代替。类型 必须enum('always', 'never', 'handled', false, true)这个是ScrollView的属性,所有继承ScrollView的都有此属性。 2.将TextInput,用ScrollView包裹起来,并且设置此属性为always或者handled(更多的时候用这个)

April 27, 2022 · 1 min · jiezi

关于react-native:Chrome-DevTools-Inspector-扩展实践

截图自:https://developer.chrome.com/... 本文作者:原草 前言云音乐 app 内有很多应用 react native 开发的利用,例如云贝核心、云音乐商城、会员中心等。为了更好地晋升开发效率,改善调试体验,团队决定开发 react native 调试工具,通过为 react native debugger 减少一些扩大性能,实现业务信息的展现和调试能力,例如:跨端通信信息展现、网络信息展现等。 因为云音乐 react native 利用的网络申请都是通过客户端发送,因而想把客户端网络信息通过 chrome devtools protocol 展现在 network 里。通过尝试后,期间遇到了一些问题和做出的尝试记录如下。 chrome devtools 介绍chrome devtools 是前端罕用的调试工具,集成在 chrome 里。web 利用通过 chrome devtools protocol 与 devtools frontend (平时关上 f12 调试面板的页面,也是个前端我的项目,上面用 frontend 示意)建设连贯,将被调试利用信息传递到 frontend 上展现。 ChromeDevTools/devtools-frontend 是 chrome devtools frontend 的我的项目代码。也能够作为独自的我的项目应用,用于自定义调试性能。我的项目内应用的 devtools frontend 是 3964 版本,新版的 frontend 对打包形式、代码构造都做了调整。 devtools frontend 模块加载通过配置近程调试端口 --remote-debugging-port=9222 启动 chrome,http://localhost:9222/ 能够看失去调试链接,例如:http://localhost:9222/devtools/inspector.html?ws=localhost:9222/devtools/page/7B2421304FE8EF659B264D4F476083DA 是一个 inspector 的地址,从 inspector.html 动手看下我的项目如何启动。 ...

April 22, 2022 · 4 min · jiezi

关于react-native:ReactNative-项目采用-Typescript-处理-Global-全局变量的方案

0、前言在一般的 React-Native 我的项目中,全局变量 Global 设置很简略,很多中央也有例子,就不赘述了。当 React-Native 我的项目中引入了 Typescript 须要重新处理一下能力应用。 1、革新 Global.ts将 setGlobal 设置为一个函数 import { Dimensions, Platform , PixelRatio } from "react-native";const OS = Platform.OSconst { width, height } = Dimensions.get('window');const setGlobal = () => { global.gMainColor = '#353F5B' global.gDevice = OS global.gScreen = { screen_width: width, screen_height: height, onePixelRatio: 1 / PixelRatio.get(), } //全局域名 global.gBaseUrl = ''}export default setGlobalApp.tsx//引入 setGlobalimport setGlobal from './common/Global';export default class App extends React.Component { componentDidMount() { //执行此函数 setGlobal() } render() { const appNav = AppNavigator() return ( <Provider theme={{ search_bar_fill: 'transparent', color_link: gMainColor }} > {appNav} </Provider> ); } }

April 11, 2022 · 1 min · jiezi

关于react-native:关于React-Native报Cannot-access-‘serviceOf‘的解决方案

最近,应用0.68.0版本的React Native构建我的项目后,在运行我的项目的时候,忽然给报了一个Cannot access 'serviceOf': it is internal in 'org.gradle.configurationcache.extensions' 的谬误,报错日志如下。 e: /Users/avishay/project/node_modules/react-native/packages/react-native-gradle-plugin/build.gradle.kts:9:49: Cannot access 'serviceOf': it is internal in 'org.gradle.configurationcache.extensions'e: /Users/avishay/project/node_modules/react-native/packages/react-native-gradle-plugin/build.gradle.kts:41:7: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: internal inline fun <reified T : Any> TaskInternal.serviceOf(): TypeVariable(T) defined in org.gradle.configurationcache.extensions上面是应用npx react-native info info Fetching system and libraries information...System: OS: macOS 11.6 CPU: (8) x64 Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz Memory: 199.65 MB / 32.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 17.0.1 - /usr/local/bin/node Yarn: 1.22.1 - /usr/local/bin/yarn npm: 8.3.0 - ~/Projects/knox/knock/node_modules/.bin/npm Watchman: 2021.11.01.00 - /usr/local/bin/watchman Managers: CocoaPods: 1.10.2 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: DriverKit 21.0.1, iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0 Android SDK: Not Found IDEs: Android Studio: 2020.3 AI-203.7717.56.2031.7583922 Xcode: 13.1/13A1030d - /usr/bin/xcodebuild Languages: Java: 11.0.10 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 17.0.2 => 17.0.2 react-native: 0.66.4 => 1000.0.0 react-native-macos: Not Found npmGlobalPackages: *react-native*: Not Found对于这个问题,咱们只须要降级gradle版本即可。关上android/gradle/wrapper/gradle-wrapper.properties,而后将gradle版本批改为7.3.3版本。 ...

April 8, 2022 · 1 min · jiezi

关于react-native:2月云短信报告出炉腾讯云重回榜首vvvvvvvvvvvvvvvvvv

导语 博睿数据(股票代码688229)十余年专一APM畛域,已为超过2000余家大型企业提供业余数据服务。依靠先进的测评技术及丰盛的行业教训,博睿数据倾力打造了一个公开通明的性能测评栏目——【Bonree指数】。该栏目致力于出现各行业的整体性能详情,为宽广运营商及网民决策提供重要参考根据。目前,测评内容蕴含券商App行情刷新及交易体验、云主机性能、云短信达到率及整体性能等。 长期以来企业短信市场始终不足主观的、可量化的服务质量监控伎俩,用以掂量实在用户在短信服务上的体验,如是否收到短信,是否能在较短时间内收到短信等等。为了解决这一问题,博睿数据依靠先进的测评技术及丰盛的行业教训,从2021年8月起开始构建中立、主观、公开通明的监控短信服务质量的云短信排行榜单,助力企业轻松掌控短信服务质量与晋升用户体验。 本排行基于Bonree Net短信网关监测产品的监控数据,定期输入评测报告,致力于解决以后企业面对诸多短信供应商无奈迅速选型,对于已有供应商短信服务的达到率、整体性能、达到时延等数据不足无效的监控伎俩等痛点问题,帮忙企业事后感知+实时监测短信服务质量,助力短信服务问题的解决形式从被动告诉向被动感知转变,及时调优短信策略,极大水平上保障精准量化企业短信的服务质量与用户体验。 评测阐明 【评测工具】Bonree Net短信网关监测产品,基于博睿数据的WAP会员能力,提供遍布全国各省市的10000+稳固在线的真机短信监测节点,在雷同的测试环境下创立短信监测工作,从实在用户角度感知业务利用体验。 【评测对象】 本报告共抉择了6家国内支流云提供商的短信服务,包含:阿里云、华为云、腾讯云、百度智能云、金山云、UCloud。 【评测周期】2022年2月 【评测范畴】综合了挪动、联通、电信三大运营商,以及山东、内蒙古、宁夏、福建、江西、新疆、上海、天津、广东、甘肃、辽宁、云南、浙江、海南、广西、河北、吉林、江苏、山西、北京、四川、陕西、湖北、安徽、河南、黑龙江、贵州、湖南28个省级行政区维度数据。 【评测内容】从达到率和整体性能两大项进行评测。 注:评测中Bonree Net与各云厂商对于短信达到的定义不雷同。云厂商将短信网关接管到短信达到回执定义为短信达到,而Bonree Net站在终端用户角度,将实在手机监测点理论接管到短信定义为短信达到,如短信网关显示发送胜利,理论手机未收到或者手机将收到的短信进行了骚扰拦挡,在博睿数据报告中均定义为未收到短信。 以下为Bonree数据钻研核心公布的《2022年2月云短信排行评测报告》: 此报告综合了24355份真机短信监测节点数据,反映了各短信运营商在短信达到率以及整体性能综合实力上的排行。 短信达到率排行榜 在2022年2月短信达到率排行榜中,总体达到率平均值为97.85%,腾讯云以98.48%的达到率夺得冠军,远高于整体均值,重回榜首。UCloud、百度智能云位列第二、第三名。 短信整体性能排行榜 1、整体性能 在2022年2月短信整体性能排行榜中,整体性能均值为10.11s。其中金山云、华为云、阿里云位列前三。值得一提的是,金山云整体性能为7.19s,远低于整体均值。此外,居于末位的百度智能云虽在整体性能上体现不尽如人意,但在短信达到率方面居于前三。 网关解决耗时在2022年2月短信网关解决耗时排行榜中,网关解决耗时均值为0.11s,与上月均值统一。百度智能云、华为云、阿里云位列前三。其中百度智能云更是将网关解决耗时管制在0.03s之内,远低于平均值,短信服务的响应十分迅速;而UCloud尽管在达到率上表现出色,其网关解决耗时却远比其余厂商要高,达到0.24s。 3、短信送达耗时 在2022年2月短信送达耗时排行榜中,短信送达耗时均值为10.00s,其中UCloud、金山云、腾讯云位列前三。须要留神的是,上月阿里云在短信送达耗时方面体现亮眼,位列第三,本月阿里云在短信送达耗时方面的体现则不尽如人意,居于末位,此外,腾讯云的排名则一路飙升至前三。 总结 总体来说,在2022年2月云短信评测中,腾讯云重回达到率榜首。其中,UCloud尽管在网关解决耗时方面上稍有落后,但在达到率、短信送达耗时上均居于前三;百度智能云虽在整体性能方面体现不尽如人意,但在达到率、短信送达耗时方面体现亮眼,均位列前三;金山云虽在短信达到率方面居于末位,但在整体性能及短信送达耗时方面体现不俗,均居于前三。 【各榜排名状况】 该榜单是以达到率为排序要害指标,达到率雷同的将依照整体性能指标进行排序。 想看“Bonree数据钻研核心”公布的更多排名?请点击文末左下角“浏览原文”。 指标释义 ² 整体性能:从Bonree Net(短信工作服务)向短信网关发出请求开始,到实在手机监测点接管到短信为止的总耗时。 ² 短信送达耗时:从短信网关将短信收回开始,到实在手机监测点接管到短信为止的耗时。 ² 网关解决耗时:从Bonree Net(短信工作服务)向短信网关发出请求开始,到Bonree Net(短信工作服务)收到短信网关的响应为止的耗时。 ² 达到率:执行监测工作的实在手机收到短信的成功率。达到率=无效监测次数/总监测次数*100%。 总监测次数:Bonree Net(短信工作服务)向短信网关收回1次短信发送申请记为1次监测。 无效监测次数:Bonree Net(短信工作服务)向短信网关收回1次短信发送申请600秒内,实在手机监测点接管到该短信记为1次无效监测。 北京博睿宏远数据科技股份有限公司 Bonree 数据钻研核心 2021.03.24公布

March 24, 2022 · 1 min · jiezi

关于react-native:React-Native原理之跨端通信机制

图片起源:https://unsplash.com/photos/g... 作者:五廿 跨端通信在挪动端开发场景中,能应用一份代码就能同时在安卓和 iOS 零碎上运行 APP 的计划,熟称为跨端计划。而 Webview ,React Native 都是云音乐大前端团队用的比拟多的跨端计划,这些计划尽管能进步开发效率,但它们不能像原生语言一样间接调用零碎的能力,于是在做 HTML5(以下简称 H5) 或者 React Native(以下简称 RN) 需要的时候,开发者们常常碰到要调用 Native 能力的状况。Native 能力用原生语言编写,有本人的运行环境,RN 页面应用 JS 编写,也有独立的运行环境,这种逾越运行环境的调用被称为跨端通信。 H5 中的跨端通信称为 JSBridge,在进行一次 JSBridge 调用的时候会携带调用参数,默认有 4 个参数: ModuleId: 模块 IDMethodId: 办法 IDparams: 参数CallbackId: JS 回调名其中 ModuleId 和 MethodId 能定位到具体调用的原生办法,params 参数作为原生办法调用的参数,最初通过 CallbackId 回调 JS 的回调函数,H5 就能从回调函数中拿到调用后果。该流程中次要应用了 Webview 容器中拦挡申请和客户端调用 JS 函数的能力,比方安卓中通常应用的是 WebChromeClient.onJsPrompt 办法来拦挡 H5 的申请,evaluateJavascript 办法用来执行回调。然而 React Native 中没有引入 Webview 来实现这些调用的能力,它采纳了齐全不同的形式来解决。另外,在云音乐团队的 APP 中, 会同时存在 H5 和 RN 页面,也就是同一个 APP 中两种跨端通信形式并存,但它们最初调用的原生办法却是来自同一个原生模块。本文次要从 Android 零碎的 RN 实现来介绍 RN 的通信机制和桥接能力(以下简称 Bridge),并联合以上通信场景中会碰到的问题来解说如何实现一个业务中可用的 Bridge。大体由三局部组成,首先介绍 RN 中不同的组成模块和它们各自的角色;第二局部是各个模块之间的调用形式和具体的示例;最初一部分探讨业务中的 Bridge 的实现。 ...

February 28, 2022 · 4 min · jiezi

关于react-native:Luna你想要的-React-Native-调试工具

本文作者:Shopee Digital Purchase 前端团队。1. 背景React Native(以下简称 RN)目前在 Shopee 前端团队失去大量利用。RN 尽管有很多劣势,然而其开发和调试流程与 Mobile Web 相比却不那么敌对,特地是在运行时的调试。 在开发模式下,尽管 RN 提供了官网的调试工具,然而相比纯前端的浏览器 Devtool,它的性能比拟弱;而非开发模式下,例如 Test 和 UAT 环境,RN 代码被打包成了一个 Bundle,这个时候官网调试工具也派不上用场了,这不仅对测试同学的问题复现产生妨碍,也使开发同学的问题定位变得更加艰难。 目前业界对于 RN 的调试尽管有工具,但或多或少都存在缺点(如下图所示),而且这些工具都是针对开发模式下的调试,对于打包后的生产环境的调试往往还是须要靠人肉去做,效率比拟低下。 因而一款可能帮忙在非开发环境定位问题的工具显得尤为重要,Luna 就此应运而生,本文将介绍这款 RN 工具关键技术的设计以及实现。 2. 性能介绍先通过上面几张图理解一下 Luna: 从图片能够看进去,Luna 是一款 RN 的利用内调试工具,更偏差于解决生产环境调试的痛点。 Luna 由一个橙色的触发按钮以及占据半屏的本体组成。本体蕴含了 Log、Network、Redux 和 Shopee 这四个版块,别离承载了日志记录、网络申请查看、Redux 树查看以及 Shopee 相干信息查看的性能。 其中,Log 和 Network 作为外围模块存在,而 Shopee 和 Redux 则是作为 Luna 提供的公共插件引入进来的。这种 Core-Plugin 模式就是 Luna 当初的运行模式:默认提供 Log、Network 等性能,也反对使用者编写自定义模块导入到 Luna。 四大版块的性能如下: 1)Log 版块 ...

January 28, 2022 · 3 min · jiezi

关于react-native:Flutter-与-React-Native-该如何选择

跨平台程序员之间对于 React Native 和 Flutter 的旷日持久的争执越来越白热化了。前几年,React Native 还是开发人员的首选框架,然而自 2017 年 Flutter 公布以来,其曾经倒退成为 React Native 的一个强有力竞争对手。 最近,随着许多初创公司抉择了 Flutter 用于 MVP 开发,React Native 正在面临来自 Flutter 的强烈竞争。那么问题来了,哪种利用开发技术将在 2022 年取得成功呢? Flutter 利用的劣势 热重载 = 疾速编码Flutter 容许开发人员应用一种更简单、更疾速的形式来创立应用程序。这是 Flutter 的最大劣势之一,也是所有顶级挪动利用开发公司都颇为看重的。 开发人员能够实时对代码库做出改良,并立即看到这些改良反映在申请中。这就是所谓的“热重载”个性,更改通常只需几毫秒就能显示进去。 这一性能让团队能够疾速增加性能、修复谬误和测试新想法。前端培训此外,当团队须要通过合作来放慢开发速度时,热重载用起来十分棘手。 实用于多个挪动平台的繁多代码库Flutter 容许开发人员为两个利用只编写一个代码库——一个针对 iOS,另一个针对 Android。因为 Flutter 具备本人的模板和布局,它的操作系统无关的平台意味着开发人员能够在两个不同的零碎上应用雷同的性能,同时放弃每个利用都有本人独特的款式、可用性和性能。 Flutter for Web 是由谷歌开发的,为开发人员提供了必要的信用保障。一旦应用程序上线,就能够用单个代码库反对 Android、iOS 和 Web 平台。 与 React Native 相比,须要的测试只有一半因为你将在两个平台上测试雷同的程序,因而质量保证流程做起来会快得多。咱们编写了的自动化测试量只有一半,因为在两个平台上能够编写雷同的测试,这样就最大水平地缩小了质量检查团队的工作量。 然而,因为你的质量检查专家必须手动查看每台设施上的利用,因而须要进行与原生编程类似级别的手动测试。 为什么有人会更喜爱 React Native 而不是 Flutter? 疾速刷新 = 疾速编码它具备与 Flutter 雷同的个性。热重载放慢了开发过程,并容许程序员将新代码直接插入正在运行的应用程序中。这样开发人员无需从新构建应用程序即可立即看到改良。 热重载能够保留应用程序的状态,并防止了在齐全重载期间失落它的危险(就基于状态的框架而言,这是一大劣势)——这进一步放慢了挪动应用程序成长的速度。 一个代码库,两个挪动平台(甚至更多!)就像 Flutter 一样,你只需编写一个代码库即可运行两个应用程序,一个跑在 Android 上,一个运行在 iOS 上。西安前端培训更好的一点是,因为用的是 JavaScript,所以你在开发跨平台应用程序时能够和 Web 利用共享代码。你只需应用可对特定平台编译的形象模块即可。 ...

January 13, 2022 · 2 min · jiezi

关于react-native:React-Native无感升级在满帮集团的实践

一、背景满帮团体挪动团队2018年初开始尝试React Native,通过近三年的倒退,目前曾经承载了大部分的外围业务场景,波及16+的业务模块、200+页面,日均PV数据在千万级。外围业务也应用React Native开发后,咱们脱离了APP发版的限度,对立应用动静发版。相比于APP发版,动静发版频率进步了很多,一周最低两版,有时一周甚至会发5个版本。 2018年上线React Native时,用的是过后比拟新的0.51版本。在后续的版本中,Facebook官网引入了诸多新的个性,比方Hooks、Hermes引擎等等。咱们持续应用0.51版本,这些新个性都无奈应用,而且社区中很多基于更新版本ReactNative的第三方库业务也无奈应用。因而,在应用0.51版本3年之后,咱们决定降级到目前较新的0.62版本。 二、0.62版本改良在之前,咱们始终应用的是0.51版本,不过,在通过近两年的迭代后,React Native公布了0.62版本,并且0.60以上版本相比之前的版本,性能有了大幅的进步,次要体现如下。 2.1 性能晋升相比于0.51版本,0.62最大的改良是,android上应用了Hermes作为JS执行引擎,在启动速度、内存占用、JS运行效率上都有十分大的晋升。 2.2 稳定性晋升从0.51版本到0.62版本,修复了大量功能性和稳定性bug,比方Native 局部的SDK的健壮性失去了很大的增强,例如Android中 ReactHostView,在 show() 和 hide() 的安全性都进行了增强。又如ViewManager 局部, 不非法时间接进行了异样解决。 2.3 社区生态ReactNative生态次要分为两局部: React 自身语言个性。0.51 应用的是 React 16.0, 0.6x 应用的是 16.11.+, 两头新增了很多令人兴奋的新个性,例如 16.2.0 的 Context 、 16.8.0 的 Hooks , 这些无疑是开发的利器! React Native、React第三方库社区的第三方库往往两年一个周期进步 React 的依赖版本,例如比拟有名到导航库 : React-Navigation , 并且减少很多实用的新个性, 例如 ReactNative 外部路由栈开始反对页面间的激活、回到后盾等个性。这在咱们日常开发中十分实用。 2.4 Android端性能0.6x开始,Android端引入了Hermes引擎,带来了很大的性能晋升。相比于JSC,Hermes最大的改良是反对间接运行JS代码预编译的产物,因而冷启动性能上有很大晋升,同时内存占用也有肯定降落,然而包体积增大了一些。 为了理解分明性能晋升数据,咱们在Android端对JSC和Hermes进行了性能比照测试,测试设施:VIVO X21 RAM:6G。 2.4.1 冷启动耗时数据从上图能够看出,Hermes+HBC的冷启动耗时相较于JSC+JS降落了50%以上,因而咱们决定应用Hermes+HBC的计划。 2.4.2 包体大小数据从上图能够看出,HBC二进制包的压缩比显著不如Jsbundle, 体积简直是后者的两倍, 然而这一点能够通过后续的拆包, 端上转化HBC 等伎俩躲避。 2.4.3 代码指令处理速度面对大量运算以及解析的时候, JSC 性能消退特地重大,而Hermes则绝对安稳, Hermes 和 JSC 耗时比根本在 1/6 左右, 杰出的处理速度对帧率、 动画晦涩度都有很大的晋升。 ...

January 9, 2022 · 3 min · jiezi

关于react-native:Reactnative-开发小技巧

1. isFocused咱们晓得对于App来说,对于页面的跳转不像PC端,Pc端如果跳转页面,则上一个页面会卸载,APP则不然,它是一个页面盖在另一个页面下面,怎么了解呢,就是以后页面盖在上一个页面上。那这个个性也就会导致咱们开发的时候须要去思考躲避二件事:1.页面不会卸载,返回的时候,不会从新申请页面 2.或者说有的是高耗费的页面不在以后页面了,也会始终在耗费手机性能这时候就要隆重介绍一个新的属性了:isFocused这个属性能够让咱们得悉:是否在以后页面,如果是:true,否则就是false长话短说间接上代码: 解决返回页面不会刷新的问题 import {useIsFocused} from "@react-navigation/native";const isFocused = useIsFocused()useEffect(()=>{ if(isFocused){ getListData() }},[isFocused])解决不在高耗费页面,还在耗费 isFocused && ( <Camera onCodeRead={(code)=>{ const url = parse(code); navigate('WebScreen',{uri:url}) }}/> )2.react-native flex布局个别咱们应用flex布局的主轴是row,然而在react-native中主轴是column 为什么会是这样呢,因为手机横屏没有竖屏长,react-native才成心这样设计的。上面的例子是兼容性的展现九宫格,每行三个。 例子1 在挪动端页面获取屏幕的宽度个别是vw,vh,然而在RN中则是这样的: import {Dimensions} from 'react-native'const {width:screenWidth,height:screenHeight} = Dimensions.get('window')export {screenHeight,screenWidth};而后设置间隙和每个盒子的宽高:整屏幕的宽度 - 两边的padding - 头像的宽度-头像右侧的宽度-两个间隙 let cellGap = 5;let cellWidth = (screenWidth - 10*2-32-10-cellGap*2)/3<View style={{ width:cellWidth, height:cellHeight, backgroundColor:"blue"}} /> 例子二: alignSelf 不听从父元素的排列规定,按本人的规定来 <View style={{ width:cellWidth, height:cellHeight, backgroundColor:"blue", alignSelf:'flex-end',}} />

January 1, 2022 · 1 min · jiezi

关于react-native:RN实现双向认证

有的时候咱们会为了APP的平安做很多措施,就比方双向认证,通过证书帮忙咱们做通信加密。咱们通过以下几个问题帮忙咱们更进一步地理解和施行。 什么是双向认证?https是双向认证吗?SSL/TLS Pinning和双向认证的区别?双向认证理论就是通信单方相互认证的一个过程,做的比拟多的就是客户端和服务端的互相认证,就是单方在通信的时候先校验下单方是否是非法的,留神是单方都要校验 有的同学就想,那https的校验过程属于双向认证吗?接下来,咱们先来看下它的过程 这里借用其它网站的一张图,这个过程理论就是SSL/TLS加密的过程 1.客户端发送申请 2.服务端把申请的证书(就是下面服务端生成的公钥私钥,实际上证书不仅蕴含这些)  发给客户端 3。客户端利用本地环境的ca证书(个别是由公共权威的机构内置在手机或电脑内)查看服务端证书合法性后,生成随机key,并用证书里的公钥加密发给服务端 4.服务端接管到后,利用私钥对客户端key的hash加密,发给客户端 5.客户端用公钥解密后看本人的key的hash是否统一 6.如果统一将会把生成的对称算法和密钥用服务端的公钥发给对方,而后就开始传输数据  通过这几个步骤咱们发现,只有客户端校验了服务端的证书,但服务端并没有对客户端进行粗疏的校验,所以咱们能够通过不同客户端向服务端发送申请。 那么问题来了,出于更高规格的平安思考,我可不可以让我的服务端只承受我APP里收回的申请呢? 前端大略思路如下: 生成自签的客户端和服务端证书,拿到前端的客户端证书和ca证书安卓端须要先将客户端证书的公钥和私钥转成p12格局,再转成bks格局;ios端p12就能够了而后通过rn的原生模块嵌入到我的项目,具体能够看下rn的官网文档这样在通信的时候,客户端收到服务端的证书会应用本人APP内嵌的自签ca证书去校验服务端,服务端也会应用自签的ca证书去校验客户端的证书,这样就能够实现只有自家的那些APP能够和服务端通信了 留神:因为APP内嵌了证书,而APP又容易解包,所以就要做好APP的防护了! 另外,有的同学可能理解过SSL Pinning,咱们晓得SSL Pinning有两种策略,一种是把服务端证书放APP,一种是放服务端的公钥,而后通过证书或公钥对服务端进行非法校验。 但不论是哪种形式,实际上还是客户端在校验服务端罢了。 参考文章: HTTP 与 HTTPS 的区别

December 31, 2021 · 1 min · jiezi

关于react-native:React-Native新架构剖析

目前 React Native 新架构所依赖的 React 18 曾经发了 beta 版,React Native 新架构面向生态库和外围开发者的文档也正式公布,React Native 团队成员 Kevin Gozali 也在最近一次访谈中谈到新架构离正式发版还差最初一步提早初始化,而最初一步工作大概会在 2022 年上半年实现。种种迹象表明,React Native 新架构真的要来了。 后面,RN官网发表:Hermes将成为React Native默认的JS引擎。在文章中,咱们简略的介绍了行将公布的新渲染器 Fabric,那么咱们重点来意识下这个新的渲染器 Fabric 。 一、Fabric1.1 基本概念Fabric 是 React Native 新架构的渲染零碎,是从老架构的渲染零碎演变而来的。外围原理是在 C++ 层对立更多的渲染逻辑,晋升与宿主平台(host platforms)互操作性,即可能在 UI 线程上同步调用JavaScript代码,渲染效率失去显著的进步。Fabric研发始于 2018 年,Facebook 外部的很多React Native 利用应用的就是新的渲染器Fabric。 在简介新渲染器(new renderer)之前,咱们先介绍几个单词和概念: 宿主平台(Host platform):React Native 嵌入的平台,比方 Android、iOS、Windows、macOS。Fabric 渲染器(Fabric Renderer):React Native 执行的 React 框架代码,和 React 在 Web 中执行代码是同一份。然而,React Native 渲染的是通用平台视图(宿主视图)而不是 DOM 节点(能够认为 DOM 是 Web 的宿主视图)。在更换了底层的渲染流程之后,Fabric 渲染器使得渲染宿主视图变得可行。Fabric 让 React 与各个平台间接通信并治理其宿主视图实例。Fabric 渲染器存在于 JavaScript 中,并且它调用的是由 C++ 代码裸露的接口。 ...

December 26, 2021 · 5 min · jiezi

关于react-native:ReactNative中metro构建缓存导致的事故

最近一次应用react-native进行构建时呈现因metro构建缓存导致的事变。 事件的起因是这样的,在babel.config.js中引入babel-plugin-root-import plugins: [ [ "babel-plugin-root-import", { "rootPathSuffix": "src/", "rootPathPrefix": "@" } ]]而后,因为@符号与npm中的一起包名抵触,像 import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'会呈现找不到无奈导入'@react-navigation/bottom-tabs'的问题,问题很容易就找到起因所在,因而将"rootPathPrefix": "@"改成"rootPathPrefix": "~".然而问题并无奈解决,在运行时还是呈现无奈导入'@react-navigation/bottom-tabs'.就算是禁用"babel-plugin-root-import"也无奈导入。 应该缓存导致的问题,因为构建打包采纳的是metro,因而查问了一下文档,通过resetCache解决了这个问题。 // metro.config.jsmodule.exports = { resetCache:true, // 减少这一行 ...}resetCache=true的作用是每次构建时均清空缓存,其默认是false,能够放慢构建速度。然而在某些状况下会呈现因缓存导致的问题。 论断: 当在运行React-Native呈现一些问题时,能够尝试通过清空缓存来解决。 进入android文件夹,运行gradlew clean,清空android构建缓存。配置metro.config.js文件中的resetCache=true,清空打构建缓存

December 24, 2021 · 1 min · jiezi

关于react-native:记录使用React-Native开发App全过程

应用相干插件 Expo(我的项目框架)、nativebase(UI框架)、React Navigation(路由)应用Expo是为了编译Web端的时候能够SSR渲染性能开发地图 应用 react-native-maps开发过程中记录safeArea ReactNavigation提供 加上会去掉顶部和底部的高度StatusBar 能够扭转状态栏问题记录轮播图插件 react-native-swiper 在Web端不能够应用 继续更新中.....

December 23, 2021 · 1 min · jiezi

关于react-native:ReactNative运行报错问题汇总-以及Taro小程序异常

RN1.本地打包失败,短少sentry配置正文 2.运行pod install的时候,use_native_modules 找不到本地的包手动批改@react-native-commutiy下的包的门路 找到这个包下的bin.js本地的门路 3.运行yarn android的时候报错手动批改android目录下的build.gradle文件,新增 4.运行yarn android的时候报错手动复制jdk文件地址(留神替换为本人的地址) sudo cp /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/lib/tools.jar /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib5.运行yarn android的时候报错手动批改android下的compileSdkVersion和targetSdkVeision为29 6.运行yarn android的时候报错 cannot find moudle react-native-pager-view at @ant-design/react-native/lib/carousel手动装置react-native-pager-view 运行yarn start的时候报错,找不到模块手动装置@react-native-picker APP拉起小程序领取后无奈返回APPhttps://developers.weixin.qq.... 此接口用户可手动触发返回App 只能返回拉起小程序的App react-native-image-picker 502手动正文android/build.gradle中圈中的局部 maven { url 'https://dl.bintray.com/umsdk/...' } 拜访不了 按图示中替换maven { url 'https://repo1.maven.org/maven2/' } RN 图片不显示xcode12导致 在文件react-native/Libraries/Image/RCTUIImageViewAnimated.m中的if (_currentFrame) {...}后加else {[super displayLayer:layer];}降级到最新的mac 零碎 monterey, xcode 13,运行yarn ios报错解决办法 Xcode报错An organization slug is required (provide with --org)在ios文件下新建sentry.properties文件 defaults.project=sentry新建的具体我的项目名defaults.org=组织名 // 比方https://sentry.xxxx.com/organizations/sentry1111/projects/,组织名为sentry1111defaults.url=https://sentry.xxxx.com // 私有化部署sentry的,取本人域名;走官网sentry的该值不须要配置,间接删除auth.token=authtoken // 这个值的获取比拟麻烦, 私有化参照上面步骤获取,官网的应该走我的项目设置间接能生成Taro我的项目编译小程序报错 taro相干依赖 要与taro-cli保持一致 ...

December 22, 2021 · 1 min · jiezi

关于react-native:又回到了和ReactNative相爱相杀的日子

最近回到了RN相干的项目组,又开始了和React-Native相爱相杀的日子。也只有RN,能让我久违的在家捣鼓(jia)技术(ban)这次又碰到什么问题呢? 一个个来讲。 依赖首先是陈词滥调的依赖装置,npm依赖我就不讲了,遇到的都是常见问题。 这次遇到的是安卓同步gradle的问题 download maven-metadata.xml卡在了download maven-metadata.xml,一开始认为是网络问题,好,我开全局vpn,我再给你足够的工夫(挂机通宵跑),总没问题了吧? 后果早上起来还是相熟的这行字download maven-metadata.xml。。。。 网上搜了下,有几种计划 用离线模式。 不行,这种解决方案是解决每次都同步的问题,我一次都没同步过,离线模式跑不了。用aliyun的仓库 不行。同步是胜利了,但编译失败。 报错找不到对应文件。批改maven地址 不行。最初通过增加--info参数从新同步,发现是拉取友盟的依赖报403,而后把仓库里友盟的maven地址搜寻一番,发现友盟换地址了。。 详见友盟布告 所以为什么公司的发版机能够失常发版? 这就是传说中的It works on my machine吗? 或者那台机器不须要同步吧。。正菜接上来上正菜,需要呢是做一个相似Dropdown的组件,后果在iOS中做完之后安卓上的成果却拉垮了。 一开始我认为是overflow: visible在安卓下不失效的老问题。起初发现当初能够了,看来RN还是有在提高的。 随后发现是measure返回的数据在Android和iOS下不统一。我的需要是拿到以后View绝对父容器的地位 安卓下间接用onLayout中返回的数据就行了。 OK,款式是失常了,然而弹出来的内容无奈点击!并且点击会穿透。详见github issue 2年了还没解决。。 让我想起了我18年给RN提的issue也还没解决。。。我发出下面RN在提高的话!!!其中也提到了一些解决办法,比方用react-native-gesture-handler中的TouchableOpacity替换RN的。 替换中后的确能点了! 然而穿透的问题没有解决。 尝试要把页面中其余的touch组件对立改成应用react-native-gesture-handler能够解决穿透问题。 然而款式却又不行了。即便把style改成了containerStyle。因为页面的布局略微有些简单,而且波及到了Pad宽屏和手机屏幕的自适应,臣妾改不动啊!! 目前想到2个最终计划 在Dropdown展现菜单的时候,disable掉页面其余的Touchable组件采纳相似Modal遮罩的计划,在顶层实现我的Dropdown,比方用react-native-root-siblings,而不是用当初的absolute形式(这种形式在web上比拟常见)计划1简略,然而不省事。 所以我大略会用计划2吧~ 完

December 5, 2021 · 1 min · jiezi

关于react-native:React-Native填坑之旅GraphQL

GraphQL还是通过Http的GET和POST的形式返回数据,只是GET的长度限度导致可能的查问会出问题。所以个别都能够用POST来获取、批改数据。这就是说GraphQL在客户端App来说能够和平时申请API的形式齐全一样。在根本应用上,有没有第三方graphql client的库的帮忙都没什么区别。 GraphQL是啥在正式开始之前,略微介绍一下GraphQL。如果你的我的项目稍有规模,那么你肯定禁受过一种折磨。一个很久之前的API返回了巨多务必的数据,是能够齐全服务当初的需要。然而显著数据过多在要求性能的时候,在后端数据是查出来的,有缓存也得拜访了缓存能力返回并不是没有代价。在前端占了带宽返回就慢。而后从一大堆数据里拿出你想要的也要代价。前面的保护对于前后端都是可能产生辣手的问题。之所以FB要提出GraphQL的规范也是因为FB自身反对的产品太多遇到了这样的问题。 如果客户端这边说有了什么需要,就获取这个需要的必要数据,那么根本就要新开发API。GraphQL就是一个你要啥就返回啥的微小API。能够查问你指定的数据,也能够批改后端的数据。查问就是Query,批改操作叫做Mutation。 查问: query { todos { id title } }这是一个查问。要查问的是todos(能够临时了解为一个表),要查问的是id和title两个字段。这个查问只会返回id和title两个字段对应的数据。 也能够是带条件的查问: query ($from: Int!, $limit: Int!) { todos (from: $from, limit: $limit) { id title } }新增、批改mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) { createReview(episode: $ep, review: $review) { stars commentary }}返回 { "data": { "createReview": { "stars": 5, "commentary": "This is a great movie!" } }}根本介绍就到这里。具体能够参考官网文档。 为啥不是Relay官网的库专职负责劝退有没有领会过。GraphQL是Facebook提出来的一个规范,留神这是一个规范而不是实现。服务端的状况不熟不多做介绍,然而在客户端FB或者当初叫Meta了,给出了一个实现并且曾经倒退了很多年。这个库叫做Relay。 它凭借弱小的性能和Meta(当年FB)背书,很快倒退了起来。不过这个工具显然曾经有点后劲不足了。从当初TypeScript我的项目倒退的状况来看,它显然不足对TypeScript的反对。比方它的一个配套babel插件没有对TypeScript的反对。当然也是一个小问题,只须要在本人的我的项目里增加一个index.d.ts文件并增加类型就能够。 而后是它的模式。在你依照官网文档的Step by step一步一步走完的话,你还是不能做开发。因为你在增加另外一个文件的和查问的时候就会发现,这个须要的查问并不会主动生成。要么是悄没声的没有报错也没有生成对应的文件,要么是报一些莫名其妙的错。因为你须要依据你的文件名来命名查问(或者任何的操作)。也就是它的模式能够认为是强侵入的,尽管会比其余的形式少写一些固定代码,尽管也不肯定。笔者程度无限,只好先弃了。 URQL怎么样首先,urql在github有6.5K的star。并且设计也足够沉闷。最初被后还有个公司反对。不能说不是KPI我的项目,然而KPI我的项目也有个益处,至多有为了KPI的人在保护代码。 另外,这个库是用TypeScript开发的。也就是说它必定是TypeScript敌对的,你的我的项目如果用了TypeScript,在类型上不必放心过期、不残缺等问题。 并不是其余的库不适合,更多能够抉择的库在GraphQL官网里有列出来。 ...

November 10, 2021 · 2 min · jiezi

关于react-native:React-Native填坑之旅使用reactredux-hooks

React hooks进去之后又关上了一道前端造轮子的大门。各种Hooks的工具满天飞。react-redux也跟上了这波潮流。 我的项目代码在这里 首先,也是最重要的一点。如果你不晓得要不要用redux,那么最好不要用。 redux次要解决的问题是对立起源的状态治理。 全局state寄存在store里。store.getState()能够取得state树。给store,发送action能够通过reducer生成新的state。store.dispatch({type:SOME_ACTION, data: {})。订阅store,或者新的state。store.subscribe(() => store.getState())。React-redux次要解决的是第二条。应用connect办法把state和actions都作为props注入到了组件里。 比方当初有一个Counter组件。increment做为action creator。状态就是value++。那么能够写成: function Counter(props) { // ... return (<Button onClick={() => props.increment()}>+</Button>)}const mapStateToProps = (state) => ({ value: state.value,});const mapActionToProps = (dispatch) => ({ increment: dispatch(increment()),})connect(mapStateToProps, mapActionToProps)(Counter);大略就是下面这样的。应用了react-redux的hooks呢,画风一转。整个显得清晰了很多。当然这里也不能少了redux toolkit的帮忙。 要实现redux利用的齐全体就少不了要创立redux的store等这些后期的配置工作。为了缩小这些繁琐的配置,redux开发了toolkit这一套工具。我的项目代码中都有,能够参考。这里不多介绍。 应用了react-redux之后看起来就是这样了。咱们在后期没有多做action(action creator)和reducer的介绍。忽然呈现不能体现它的简化后的益处。有一点,action和reducer通常都放在不同的中央。应用起来不是非常不便。 在新的实现中这些都在slice文件中,不便对立的治理。保护起来也好很多。 import { createSlice } from '@reduxjs/toolkit';export const counterSlice = createSlice({ name: 'counter', initialState: { value: 0, }, reducers: { increment: state => { state.value += 1; }, decrement: state => { state.value -= 1; }, incrementByAmount: (state, action) => { state.value += action.payload; }, },});// Action creators are generated for each case reducer functionexport const { increment, decrement, incrementByAmount } = counterSlice.actions;这是应用了redux toolkit的益处。action的局部根本不必解决。它会主动生成进去action creator。 ...

October 28, 2021 · 1 min · jiezi

关于react-native:React-Native填坑之旅React-Native-Web

如果你应用react native开发了app,会不会想有一个站点呢。如果你想,那么react-native-web就有用武之地了。只有不是平台相干的组件根本都能够复用,包含js款式。更不用说内置的accessibility。 react-native-web比拟偏向于举荐expo的,更多的介绍是对于create-react-app生成的代码的。然而这篇文章是对于曾经能存在的mobile的我的项目而言的。这是一种更急广泛,或者更须要这篇文章的状况。 代码在这里 增加依赖要是应用react-native-web首先要增加必须的依赖。首先跳转到我的项目的根目录 cd path-to-your-project先把react-native-web加上 yarn add react-native-web而后相干依赖 yarn add -D babel-plugin-react-native-web webpack webpack-cli webpack-dev-server html-webpack-plugin react-dom babel-loader url-loader @svgr/webpack如果你有前端的开发教训的话,看看咱们当初我的项目的构造你会发现少了很多。作为一个单页利用,单页都还没有呢。dev server和打包的老大哥webpack也没有。这些咱们也都要一一加上。 index.html <!DOCTYPE html><html> <!-- 略 --> <body> <div id="app-root"></div> </body></html>这个就是单页利用的那个单页。是作为整个app的承载页。所有的js都运行在这个页面里。 webpack.config.js // ...const compileNodeModules = [ // 增加须要编译的react-native包].map((moduleName) => path.resolve(appDirectory, `node_modules/${moduleName}`));// ...webpack是打包工具。开发的时候跑dev server,发生产的时候打生产包。这里须要制订webpack把依赖到的包都编译了。 如果你不这么做的话,大概率你会遇到这个么一个报错。比方你用了react-native-gesture-handler。 ERROR in ./node_modules/react-native-gesture-handlerModule parse failed: Unexpected tokenYou may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders而后咱们也会增加所有须要编译的代码。比方index.web.js,App.web.tsx。还有src目录下的所有代码,以及上文提到的所有的库。 ...

October 28, 2021 · 2 min · jiezi

关于react-native:React-Native填坑之旅-Whats-next

记录一下前面要写的: Redux hooksGesture responder systemNew navigationWebBrief instroduction of desktop dev

October 27, 2021 · 1 min · jiezi

关于react-native:React-Native填坑之旅TurboModule之iOS

iOS啥都不必干,又或者是FB还没来得及改? https://github.com/facebook/r... /* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */#import "RCTDeviceInfo.h"#import <FBReactNativeSpec/FBReactNativeSpec.h>#import <React/RCTAccessibilityManager.h>#import <React/RCTAssert.h>#import <React/RCTConstants.h>#import <React/RCTEventDispatcher.h>#import <React/RCTUIUtils.h>#import <React/RCTUtils.h>#import "CoreModulesPlugins.h"using namespace facebook::react;@interface RCTDeviceInfo () <NativeDeviceInfoSpec>@end@implementation RCTDeviceInfo {#if !TARGET_OS_TV UIInterfaceOrientation _currentInterfaceOrientation; NSDictionary *_currentInterfaceDimensions;#endif}@synthesize bridge = _bridge;RCT_EXPORT_MODULE()+ (BOOL)requiresMainQueueSetup{ return YES;}- (dispatch_queue_t)methodQueue{ return dispatch_get_main_queue();}- (void)setBridge:(RCTBridge *)bridge{ _bridge = bridge; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveNewContentSizeMultiplier) name:RCTAccessibilityManagerDidUpdateMultiplierNotification object:_bridge.accessibilityManager];#if !TARGET_OS_TV _currentInterfaceOrientation = [RCTSharedApplication() statusBarOrientation]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interfaceOrientationDidChange) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; _currentInterfaceDimensions = RCTExportedDimensions(_bridge); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interfaceFrameDidChange) name:UIApplicationDidBecomeActiveNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interfaceFrameDidChange) name:RCTUserInterfaceStyleDidChangeNotification object:nil];#endif}static BOOL RCTIsIPhoneX(){ static BOOL isIPhoneX = NO; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ RCTAssertMainQueue(); CGSize screenSize = [UIScreen mainScreen].nativeBounds.size; CGSize iPhoneXScreenSize = CGSizeMake(1125, 2436); CGSize iPhoneXMaxScreenSize = CGSizeMake(1242, 2688); CGSize iPhoneXRScreenSize = CGSizeMake(828, 1792); isIPhoneX = CGSizeEqualToSize(screenSize, iPhoneXScreenSize) || CGSizeEqualToSize(screenSize, iPhoneXMaxScreenSize) || CGSizeEqualToSize(screenSize, iPhoneXRScreenSize); }); return isIPhoneX;}static NSDictionary *RCTExportedDimensions(RCTBridge *bridge){ RCTAssertMainQueue(); RCTDimensions dimensions = RCTGetDimensions(bridge.accessibilityManager.multiplier); __typeof(dimensions.window) window = dimensions.window; NSDictionary<NSString *, NSNumber *> *dimsWindow = @{ @"width" : @(window.width), @"height" : @(window.height), @"scale" : @(window.scale), @"fontScale" : @(window.fontScale) }; __typeof(dimensions.screen) screen = dimensions.screen; NSDictionary<NSString *, NSNumber *> *dimsScreen = @{ @"width" : @(screen.width), @"height" : @(screen.height), @"scale" : @(screen.scale), @"fontScale" : @(screen.fontScale) }; return @{@"window" : dimsWindow, @"screen" : dimsScreen};}- (NSDictionary<NSString *, id> *)constantsToExport{ return [self getConstants];}- (NSDictionary<NSString *, id> *)getConstants{ return @{ @"Dimensions" : RCTExportedDimensions(_bridge), // Note: // This prop is deprecated and will be removed in a future release. // Please use this only for a quick and temporary solution. // Use <SafeAreaView> instead. @"isIPhoneX_deprecated" : @(RCTIsIPhoneX()), };}- (void)didReceiveNewContentSizeMultiplier{ RCTBridge *bridge = _bridge; RCTExecuteOnMainQueue(^{ // Report the event across the bridge.#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wdeprecated-declarations" [bridge.eventDispatcher sendDeviceEventWithName:@"didUpdateDimensions" body:RCTExportedDimensions(bridge)];#pragma clang diagnostic pop });}#if !TARGET_OS_TV- (void)interfaceOrientationDidChange{ __weak __typeof(self) weakSelf = self; RCTExecuteOnMainQueue(^{ [weakSelf _interfaceOrientationDidChange]; });}- (void)_interfaceOrientationDidChange{ UIInterfaceOrientation nextOrientation = [RCTSharedApplication() statusBarOrientation]; // Update when we go from portrait to landscape, or landscape to portrait if ((UIInterfaceOrientationIsPortrait(_currentInterfaceOrientation) && !UIInterfaceOrientationIsPortrait(nextOrientation)) || (UIInterfaceOrientationIsLandscape(_currentInterfaceOrientation) && !UIInterfaceOrientationIsLandscape(nextOrientation))) {#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wdeprecated-declarations" [_bridge.eventDispatcher sendDeviceEventWithName:@"didUpdateDimensions" body:RCTExportedDimensions(_bridge)];#pragma clang diagnostic pop } _currentInterfaceOrientation = nextOrientation;}- (void)interfaceFrameDidChange{ __weak __typeof(self) weakSelf = self; RCTExecuteOnMainQueue(^{ [weakSelf _interfaceFrameDidChange]; });}- (void)_interfaceFrameDidChange{ NSDictionary *nextInterfaceDimensions = RCTExportedDimensions(_bridge); if (!([nextInterfaceDimensions isEqual:_currentInterfaceDimensions])) {#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wdeprecated-declarations" [_bridge.eventDispatcher sendDeviceEventWithName:@"didUpdateDimensions" body:nextInterfaceDimensions];#pragma clang diagnostic pop } _currentInterfaceDimensions = nextInterfaceDimensions;}#endif // TARGET_OS_TV- (std::shared_ptr<TurboModule>)getTurboModule:(const ObjCTurboModule::InitParams &)params{ return std::make_shared<NativeDeviceInfoSpecJSI>(params);}@endClass RCTDeviceInfoCls(void){ return RCTDeviceInfo.class;}

October 16, 2021 · 2 min · jiezi

关于react-native:React-Native填坑之旅开启TurboModuleAndroid

FB宣传了N多年的新架构预计很多人都熟知了。最次要的改良就是从所有通信都通过异步Bridge的形式转为间接通信的形式。缩小音讯通信提早,进步性能。这其中最要害的就是TurboModule。 开启TurboModule开启TurboModule没有文档。只有就的原生module里夹杂着只言片语。一个例子就把开发同学带到react-native的代码里了。这阐明官网早就反对这个机制了,只是没正式官宣。然而复杂度太高,还须要对react-native的repo代码构造有理解。还有一个更好的例子react-native-animated。 这个我的项目大小适中,构造也不那么简单。很适宜类比钻研,实现。 实现NativeModule和之前一样,继承ReactContextBaseJavaModule。具体能够参考这里。实现getName办法。 增加ReactModule注解这是和之前的形式不同的一点。 当初代码看起来是这样的: @ReactModule(name = ReanimatedModule.NAME)public class ReanimatedModule extends ReactContextBaseJavaModule { public static final String NAME = "ReanimatedModule"; public ReanimatedModule(ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { return NAME; }}最初增加ReactMethod @ReactMethod public void animateNextTransition(int tag, ReadableMap config) { mTransitionManager.animateNextTransition(tag, config); }原生模块这部分就完事儿了。上面看看如何注册这个原生模块。 注册原生模块这个局部就是重点了。上一节,和之前开发原生模块惟一不同的点就是多了一个@ReactModule的注解。这一部分不同的中央就有点多,依照官网的说法是比之前略微多了几步。 1. 增加一个继承了TurboReactPackage的类public class ReanimatedPackage extends TurboReactPackage {}2. 实现getModule办法 @Override public NativeModule getModule(String name, ReactApplicationContext reactContext) { if (name.equals(ReanimatedModule.NAME)) { return new ReanimatedModule(reactContext); } return null; }3. 实现getReactModuleInfoProvider @Override public ReactModuleInfoProvider getReactModuleInfoProvider() { Class<? extends NativeModule>[] moduleList = new Class[] { ReanimatedModule.class, ReanimatedUIManager.class, }; final Map<String, ReactModuleInfo> reactModuleInfoMap = new HashMap<>(); for (Class<? extends NativeModule> moduleClass : moduleList) { ReactModule reactModule = moduleClass.getAnnotation(ReactModule.class); reactModuleInfoMap.put( reactModule.name(), new ReactModuleInfo( // * reactModule.name(), moduleClass.getName(), true, reactModule.needsEagerInit(), reactModule.hasConstants(), reactModule.isCxxModule(), TurboModule.class.isAssignableFrom(moduleClass))); } return new ReactModuleInfoProvider() { @Override public Map<String, ReactModuleInfo> getReactModuleInfos() { return reactModuleInfoMap; } }; }在这里Module的名字仍然表演了重要的角色,它是把前(JS)后(原生),在原生里注册的多个原生模块之间如何找到那个模块都须要这模块名称。所以在初始化ReactModuleInfo的时候第一个参数就是模块名称。 ...

October 16, 2021 · 1 min · jiezi

关于react-native:React-Native填坑之旅使用原生视图Android

应用原生试图,在RN里是必不可少的一部分。如果有人在原生性能都做好了,间接拿来用或者微调一下试图局部就能够用也就不须要再另外造一个,一套轮子了。 步骤官网文档十分具体了。间接援用如下: 1. 新建一个ViewManager子类2. 实现createViewInstance办法3. 通过注解@ReactProp或者@ReactPropGroup裸露视图的属性4. 在createViewManagers办法里注册这个manager5. 实现JS模块和原生模块的开发根本一个流程。然而,首先要有一个原生视图。是这样的: public class FillingHoleView extends View { // ... public float getRadius() public void setRadius(float radius) public int getStrokeColor() public void setStrokeColor(int color) onDraw onMeasure // ...}就是一个Android的视图,画一个圈。能够通过setter管制圈的色彩和半径。 而后就开始依照下面的程序开始增加代码。 ViewManager子类public class FillingHoleViewManager extends SimpleViewManager<FillingHoleView> { public static final String REACT_CLASS = "FillingHoleView"; ReactApplicationContext mCallerContext; public FillingHoleViewManager(ReactApplicationContext reactContext) { this.mCallerContext = reactContext; } @NonNull @Override public String getName() { return REACT_CLASS; } @NonNull @Override protected FillingHoleView createViewInstance(@NonNull ThemedReactContext reactContext) { return new FillingHoleView(reactContext); } @ReactProp(name = "radius", defaultFloat = 50f) public void setRadius(FillingHoleView fillingHoleView, int radius) { fillingHoleView.setRadius(radius); } @ReactProp(name = "color", defaultInt = 1) public void setStrokeColor(FillingHoleView fillingHoleView, int color) { fillingHoleView.setStrokeColor(Color.RED); }}应用SimpleViewManager有一个益处,它默认提供了背景色、透明度和Flex布局的性能,还有一些accessbility的性能。所以继承了这个view manager就能够应用flex布局了。 ...

October 7, 2021 · 2 min · jiezi

关于react-native:React-Native填坑之旅-从Native发事件给JS

代码在这里 很多时候咱们须要从原生发送事件给JS。比方在官网文档提到的一个日历事件。你定好了一个会议,或者一个流动,之后再指定的日期产生。或者敞开了奉献单车,蓝牙收到关锁胜利的信号。又或者天文围栏这样的APP,在你进入/来到一个天文围栏的时候,都须要从原生发送事件给JS。 首先是一个简略的例子调用一个原生办法设置一个延时触发的原生工夫,相似于调用原生的setTimeout。在到工夫之后一个事件会从原生发送到JS。 首先UI上会有一个能够输出工夫的文本框,在用户输出了工夫并点击了OK按钮之后。App就会调用原生办法执行原生的setTimeout办法。 App调用的原生办法是一个在前端的promise办法。所以,这个办法能够用async-await调用。 在JS的局部会注册一个事件的监听器,一但收到原生事件就会执行JS代码。在本例中为了简略只是输入了一条log。 既然是从原生接管和发送事件,那么一个原生的模块是必不可少的。还不是很理解这部分的同学能够移步到这是iOS的,这是Android的 一点须要更新的是,当初官网举荐在实现Android原生模块的时候应用`ReactContextBaseJavaModule`。次要是出于类型平安的思考。在iOS实现一个原生模块// header file@interface FillingHoleModule: RCTEventEmitter<RCTBridgeModule>@end// implementation#import "FillingHoleModule.h"@implementation FillingHoleModuleRCT_EXPORT_MODULE(FillingHoleModule)RCT_EXPORT_METHOD(sendEventInSeconds: (NSUInteger) seconds resolver:(RCTPromiseResolveBlock) resolverejecter: (RCTPromiseRejectBlock) reject) { @try { dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * seconds); dispatch_after(delay, dispatch_get_main_queue(), ^(void) { [self sendEventWithName:@"FillingHole" body:@{@"filling": @"hole", @"with": @"RN"}]; }); NSLog(@"Resolved"); resolve(@"done"); } @catch (NSException *exception) { NSLog(@"Rejected %@", exception); reject(@"Failed", @"Cannot setup timeout", nil); }}- (NSArray<NSString *> *)supportedEvents { return @[@"FillingHole"];}@end这里省略了模块头文件。1: 在头文件里能够看到原生模块继承了RCTEventEmitter。 2: 所以在实现的时候须要实现这个类的办法supportedEvents。就是把咱们要从原生发送的事件的名字加进去。如: - (NSArray<NSString *> *)supportedEvents { return @[@"FillingHole"];}3: 在办法sendEventInSeconds里的try-catch能够辅助调用resolve和reject正好实现了JS局部的promise ...

October 4, 2021 · 2 min · jiezi

关于react-native:RN动态加载

react-native-dynamic-loadhttps://github.com/MrGaoGang/... react-native dynamic load bundle from remote; SupportiOS/Android dynamic load jsbundle/common bundle;iOS/Android supports simultaneous loading of multiple bundles实现逻辑分包如何进行分包?点击ReactNative 分包计划介绍 # ios运行npm run build:ios# android运行npm run build:android会主动进行分包,如果想要打包后的产物为数字类型,则在compile/metro-base.js中设置moduleIdByIndex=true即可 iOS 客户端动静加载// 在利用启动的时候加载 jsbundle 根底包[BridgeManager.instance loadBaseBundleWithLaunchOptions:launchOptions];// 在须要的时候加载业务包// 此处只是应用加载本地的bundle的形式,如果是在线的形式,能够先应用http下载而后加载本地[BridgeManager.instance loadBusinessBundle:@"business.ios" moduleName:@"ReactNativeDynamic" callback:^(BOOL succeed) { if (succeed) { RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:BridgeManager.instance.commonBridge moduleName:@"ReactNativeDynamic" initialProperties:nil]; self.view = rootView; } NSLog(@"%d",succeed); }];Android 客户端动静加载// 利用启动的时候SoLoader.init(this, /* native exopackage */ false);ReactAppRuntime.init(this);// 你的activitypublic class MainActivity extends DynamicReactActivity { @Override protected RnBundle getBundle(){ RnBundle bundle = new RnBundle(); bundle.scriptType = ScriptType.ASSET; bundle.scriptPath = "business.android.bundle"; bundle.scriptUrl = "business.android.bundle"; bundle.appName = "ReactNativeDynamic"; return bundle; }}

August 16, 2021 · 1 min · jiezi

关于react-native:React-Native-SDK-升级问题及分包方案

文章首发集体博客: 高学生的博客 背景: 咱们团队始终是将 ReactNative(下文简称 RN)当做一个子模块集成到现有的 android/ios 利用中;起初应用的 RN 版本是 0.55;随着时代的变迁,RN 曾经到 0.65 的版本了;降级跨度较大;上面我这边就最近 SDK 降级所遇到的问题进行一个简略的总结。 问题 1: RN 如何进行分包前言在之前的旧版本 RN 中的 metro 临时还不反对应用processModuleFilter 进行模块过滤;如果你 google 一下 RN 分包,会发现很难有一篇文章具体去介绍 RN 怎么进行分包;本文将具体讲述如何进行 RN 分包; RN 分包,在新版的 metro 中其实大多数咱们只须要关注 metro 的两个 api: createModuleIdFactory: 给 RN 的每个模块创立一个惟一的 id;processModuleFilter: 抉择以后构建须要哪些模块首先咱们来谈一谈如何给给个模块取一个 Id 名称,依照 metro 自带的 id 取名是依照数字进行自增长的: function createModuleIdFactory() { const fileToIdMap = new Map(); let nextId = 0; return (path) => { let id = fileToIdMap.get(path); if (typeof id !== "number") { id = nextId++; fileToIdMap.set(path, id); } return id; };}依照这样,moduleId 会顺次从 0 开始进行递增; ...

August 13, 2021 · 5 min · jiezi

关于react-native:React-Native-无限列表的优化与实践

导语本文介绍了在应用 React Native 开发过程中,如何对有限列表组件进行技术选型,如何应用RecyclerListView组件对有限列表进行性能优化,如何解决有限列表与标签页搭配应用时的内存优化与手势重叠的问题,心愿对大家有所启发。 背景对于分类信息流状态的产品,用户通过左右滑动切换分类,通过一直上滑来浏览更多的信息。 用标签页(Tabs)实现切换分类,用有限列表(List)实现上滑浏览手势上滑,页面向上滚动,展现更多列表项(List Item)手势左滑,页面向左滚动,展现左边的列表(蓝色) 因为 React Native(RN) 能够用较低的老本,同时满足用户体验、疾速迭代,和跨App开发上线的要求。所以,对于分类信息流状态的产品技术选型应用的是RN。在应用 RN 开发首页的过程中,咱们填过很多坑,心愿这些填坑教训,对读者有借鉴意义。第一,RN 官网提供的有限列表(ListView/FlatList)性能太差,始终被业内吐槽。通过实际比照,咱们抉择了内存管理效率更优的第三方组件——RecyclerListView。 第二,RecyclerListView 须要晓得每个列表项的高度,能力正确渲染。如果,列表项高度不确定,怎么解决? 第三,标签页和有限列表组合应用时,会遇到一些问题。首先,标签页中有多个有限列表,怎么无效治理内存?其次,标签页能够左右滑动,有限列表中也有左右滚动的内容组件,二者手势区域重叠时,如何指定组件优先解决? 列表的技术选型 ListView在实际开发分类信息流状态的产品过程中,咱们开始尝试过应用 RN,版本是 0.28。过后,有限列表用的是官网提供的 ListView 。ListView 的列表项始终不会被销毁,这会导致内存一直减少,导致卡顿。前100 条信息滚动十分晦涩,200 条时就开始卡顿,到 1000 条时就根本就滑不动了。过后,也没有特地好的解决方案,只能在产品上进行斗争,将有限列表降级为无限列表。 FlatListFlatList 是在 RN 0.43 版本新增的,领有内存回收的性能,能够用来实现有限列表。咱们第一工夫就跟进了,把 RN 版本进行降级。尽管,FlatList 能够实现有限列表,但体验上总归还是有所欠缺的。FlatList 在 iOS 体现很晦涩,但在 Android 某些机型上会有略有卡顿。RecyclerListView在实际开发中,咱们技术选型还尝试采纳了 RecyclerListView。RecyclerListView 实现了内存的复用,性能也是更好。无论是iOS 还是 Android 都体现的很晦涩。晦涩度比照掂量晦涩度的要害指标是帧率,帧率越高越晦涩,越低越卡顿。咱们用 RecyclerListView 和 FlatList 别离实现了雷同性能的有限列表,在Android 手机中进行了测试,滚动帧率如下。 滚动帧率比照(以Android OPPO R9 为例) 实现原理比照ListView 、FlatList、RecyclerListView 都是 RN 的列表组件,为什么它们之间性能差距这么大?咱们对其实现原理进行了一些钻研。 ListView ListView的实现思路比较简单,当用户上滑加载新的列表内容时,会一直地新增列表项。每次新增,都会导致内存减少,减少到肯定水平后,可应用的内存空间有余,页面就会呈现卡顿。FlatList FlatList取了个巧,既然用户只能看到手机屏幕里的内容,那么只用将用户看到的(可视区域)和行将看到的(凑近可视区域)局部渲染进去就行了。而用户看不到的中央(远离可视区域),就删掉,用空白元素占位就行。这样,空白区域的内存就失去了开释。要实现有限加载,必须要思考如何高效利用内存。FlatList “删除一个,新增一个” 是一个思路。RecyclerListView “构造相似,改改再用” 是另一个思路。RecyclerListView RecyclerListView假如列表项的品种可枚举的。所有列表项能够分为若干类,比方,一张图片的图文布局是一类,两张图片的图文布局是一类,只有布局类似就是同一类列表项。开发者,须要对类型进行当时的申明。const types = {ONE_IMAGE: 'ONE_IMAGE', // 一张图片的图文布局TWO_IMAGE: 'TWO_IMAGE' // 两张图片的图文布局}如果,用户行将看见的列表项,和用户看不见的列表项,类型一样。就把用户看不见的列表,批改成用户行将看到的列表项。批改不波及到组件的整体构造,只波及组件的属性参数,通常包含,文本、图片地址,还有展现的地位。 {/ 把用户看不见的列表项 /} <View style={{position: 'absolute', top: disappeared}}> ...

July 9, 2021 · 3 min · jiezi

关于react-native:跟着react-native-官网配置环境并且初始化项目-遇到的问题

当我什么都配置好了的时候初始化我的项目 执行npx react-native init AwesomeTSProject --template react-native-template-typescript 而后cmd提醒是上面这样的 Need to install the following packages: react-native Ok to proceed? 我输出Y 然而我的文件夹内没有任何初始化的文件在外面如下图: 我就纳闷啊 为啥什么都没有,起初我执行了 yarn add react-native 如图 而后再执行npx react-native init AwesomeTSProject --template react-native-template-typescript 就有了尽管我解决了这个问题,然而我还是有点懵逼,为啥须要我本人去独自 yarn add react-native 难道是提醒 我Need to install react-native 的时候我抉择Y 不是帮我去 yarn add react-native?

June 6, 2021 · 1 min · jiezi

关于react-native:react-native-drawer

前言我的App应用程序上须要一个抽屉菜单。React navigation drawer导航反对此性能,然而扭转了屏幕的构造,我不心愿更改,因为我只是其中一个屏幕上须要用到这个简略抽屉菜单组件。大抵的成果如下: 装置依赖react-native-modal 组件大抵能够满足我的需要,模态框加上左右移入移出的动画加上手势根本能实现侧拉抽屉的组件。当初装置它: yarn add react-native-modal -save编写SideMenu.jsSideMenu组件是侧拉菜单外面展现的内容 import React from 'react';import { Text, View, SafeAreaView } from 'react-native';import styles from './styles';const Title = ({ title }) => { return <Text style={styles.title}>{title}</Text>;};const SwitchText = ({ text }) => { return <Text style={styles.switchText}>{text}</Text>;};const Description = ({ text }) => { return <Text style={styles.description}>{text}</Text>;};const SideMenu = props => { return ( <SafeAreaView style={styles.safeAreaView}> <View style={styles.container}> <Title title="Timeline" /> <View> <View style={styles.swithBlock}> <SwitchText text="Ratings with reviews only" /> </View> <Description text="When enabled, on your timeline we will only show ratings with reviews." /> </View> </View> <View style={styles.footer}> <Text style={styles.link}>Press to call parent function</Text> </View> </SafeAreaView> );};export default SideMenu;import { StyleSheet } from 'react-native';import { screenSize } from '../../../utils/tools';const styles = StyleSheet.create({ safeAreaView: { flex: 1, backgroundColor: '#fff' }, container: { margin: 12, flex: 1 }, title: { marginTop: 15, marginBottom: 10, color: '#444', fontSize: 14 }, swithBlock: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }, switchText: { fontSize: 14, color: '#222' }, link: { padding: 5, color: '#892853' }, description: { fontSize: 13, color: '#555', marginTop: 12, marginBottom: 6 }});export default styles;编写主页面援用组件,通过isVisible参数管制菜单显示暗藏,toggleSideMenu 办法管制切换显示暗藏,还有一些管制入场动画的参数。我为了使它更靠近抽屉组件,所以应用slideInLeft 。 ...

May 18, 2021 · 4 min · jiezi

关于react-native:React-Native项目中集成reactnativevectoricons

应用React Native开发挪动App时,常常会遇到矢量图和自定义字体的开发需要,应用矢量图能够无效的缩小包体积的大小。在React Native开发中,能够应用react-native-vector-icons来满足开发需要。 一、装置和其余的第三方库一样,应用第三方库之前须要先装置react-native-vector-icons。 npm install --save react-native-vector-icons而后,在应用link命令增加原生库链接。 react-native link react-native-vector-icons二、原生端配置2.1 iOS端配置首先,在RN的 ios 目录下执行 pod install命令装置依赖包。 cd ios && pod install而后,在Xcode我的项目中创立一个新的字体组取名为Fonts,从 ./node_modules/react-native-vector-icons/Fonts将须要的字体拷贝进去。关上Xcode,应用源代码模式编辑 info.plist 文件,如下图。而后,将字体的配置退出进去,如下所示。 <key>UIAppFonts</key> <array> <string>AntDesign.ttf</string> <string>Entypo.ttf</string> <string>EvilIcons.ttf</string> <string>Feather.ttf</string> <string>FontAwesome.ttf</string> <string>FontAwesome5_Brands.ttf</string> ... </array>应用Xcode编译一下iOS我的项目,如果没有任何谬误就阐明配置好了。 2.2 Android端配置和 iOS 一样,Android原生端也须要进行一些配置能力失常应用。首先,将node-modeles\react-native-vector-icons\Fonts 目录下文件复制到我的项目andriod\app\src\main\assets\fonts 目录下。而后,关上andriod/app/build.gradle文件,减少如下代码。 apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"从新编译Android工程,如果没有任何谬误,阐明配置好了。 2.3 应用示例原生端配置实现之后,接下来就能够间接应用了,如下所示。 import Icon from 'react-native-vector-icons/FontAwesome';<Icon name="rocket" size={30} color="#900" />参考:react-native-vector-icons

May 8, 2021 · 1 min · jiezi

关于react-native:react-native项目中使用iconfont

前言react native我的项目中常常会用到icon,react-native-vector-icons字体库解决了一部分icon的需要,然而还有一部分设计师给的icon须要在iconfont自行援用,对于应用react-native-vector-icons遇到的坑在之前的文章提到过react native新建我的项目踩坑记录(字体问题详见问题五),次要是两点: 不要link react-native-vector-icons 库应用react-native unlink react-native-vector-iconsios门路下Info.plist文件增加字体映射,详见<key>UIAppFonts</key>的值ios环境下援用iconfont下载iconfont,解压后会失去其中一个iconfont.ttf的字体文件。在rn我的项目src(react业务代码根目录)下新建assets/fonts目录,复制解压后的t关上package.json文件,配置字体门路: "rnpm": { "assets": [ "./src/assets/fonts/" ]}执行以下命令,执行实现后,重启编辑器(留神文章结尾揭示的,如果有装置react-native-vector-icons字体库的,这里你link后运行我的项目必定报错了,须要反复结尾的两个步骤),link后如果不执行第四步,你xcode关上你的ios我的项目,可能是没有Resource目录的如果执行完第四步,重启后会发现该字体文件曾经主动拷贝到 android/app/src/main/assets/fonts目录和配置到Info.plist文件中, 那么你能够间接看最初一步。如果没有呈现第六步所诉的预期,那么,此时你再关上xcode,应该有Resource这个目录了,如果之前原本就有的能够疏忽这句话复制ttf文件到Resource目录下,松开鼠标会弹出来弹窗,抉择去Info.plist中增加 Fonts provided by application,而后在其底下增加子项,value值为字体文件名称,如有多个,则增加多个子项,一个子项对应一个字体文件增加完去rn我的项目下ios门路下的Info.plist文件查看字体残缺配置: <key>UIAppFonts</key><array> <string>iconfont.ttf</string> <string>AntDesign.ttf</string> <string>Entypo.ttf</string> <string>EvilIcons.ttf</string> <string>Feather.ttf</string> <string>FontAwesome.ttf</string> <string>FontAwesome5_Brands.ttf</string> <string>FontAwesome5_Regular.ttf</string> <string>FontAwesome5_Solid.ttf</string> <string>Fontisto.ttf</string> <string>Foundation.ttf</string> <string>Ionicons.ttf</string> <string>MaterialCommunityIcons.ttf</string> <string>MaterialIcons.ttf</string> <string>Octicons.ttf</string> <string>SimpleLineIcons.ttf</string> <string>Zocial.ttf</string></array>应用unicode显示字体成果安卓环境下援用iconfont待补充...

April 30, 2021 · 1 min · jiezi

关于react-native:reactnative-图片选取与上传

装置图片抉择插件 react-native-syan-image-picker 或 react-native-image-crop-picker,0.6以上版本无需手动link,具体插件配置参考GitHub链接本次需要有多选性能 选取应用react-native-syan-image-picker 示例代码:const [imageList, setImageList] = useState<UploadFileResItem[]>([]); // 插件配置参数 具体参见插件配置文档 const options = { imageCount: 6, isCrop: false, }; // 用户点击按钮选取图片 const selectImage = () => { SyanImagePicker.asyncShowImagePicker(options) .then((photos: SelectedPhoto[]) => { // 解决选取后果 后果蕴含本地文件门路 // 因为后端 不反对多文件同时上传应用promise all实现屡次上传申请 const fetchList = photos.map((item) => upload(item)); Promise.all(fetchList).then((res) => { setImageList((v) => [...v, ...res]); }); }) .catch((err) => { console.log('err', err); // 勾销抉择,err.message为"勾销" }); }; const upload = (data: SelectedPhoto) => { const formData = new FormData(); formData.append('file', { uri: data.uri, // 本地文件门路 type: 'multipart/form-data', name: 'xxxx.jpg', // 图片名称 }); return uploadImage(formData).then((res) => res.data); };注意事项上传过程中不要应用react-native-debugger调试,react-native-debugger会将formdata内容转换为string,造成上传失败,倡议应用flipper察看申请 ...

April 15, 2021 · 1 min · jiezi

关于react-native:reactnativedebugger-简单配置使用

默认的debugger-ui只能看一些console的内容,发现network看不了申请信息,看了官网发现有这么一个工具。以下是官网原话: 留神:应用 Chrome 调试目前无奈观测到 React Native 中的网络申请,你能够应用第三方的react-native-debugger来进行观测。好了,依照官网的举荐下载了这么一个调试工具,据说能够抓包。下载后关上工具,在工具栏的Debugger中找到open config file关上配置文件批改配置文件中的defaultNetworkInspect选项(将永恒启用网络查看)。设置为true即可监听网络申请reload模拟器后查看network,胜利!

April 11, 2021 · 1 min · jiezi

关于react-native:React-Native-mac环境下解决iOS-9以上系统对HTTP请求的限制

问题新搭建的一个我的项目,在应用fetch进行网络申请的时候遇到一个报错:TypeError: Network request failed.尝试间接在浏览器关上url拜访能够失常拿到返回值。(url是http协定) 起因这个API申请是http的协定申请,在iOS9以上零碎,曾经把http协定的申请限度了。iOS9引入了新个性App Transport Security (ATS)。详情:App Transport Security (ATS)新个性要求App内拜访的网络必须应用HTTPS协定。 解决方案在xcode中关上react native中的ios我的项目根目录;关上我的项目下的info.plist文件;在App Transport Security Settings下新增Allow Arbitrary Loads,值为YES;重启react native我的项目,刷新,申请后返回值失常;

April 10, 2021 · 1 min · jiezi

关于react.js:开始学习reactnative零

明天入职新公司,开发技术实用react-native,而我之前始终用的都是react,对挪动端的RN并不是很理解,也算是从零开始学习吧!在这里写学习的心得,过程和后果。看到这些文章的人,如果发现有谬误的中央,还望在评论区给我指出来。RN的大略了解是这样的:RN的文件一开始也是要引入react的,也就是这句代码import react from ‘react’跟react是截然不同的,代表此文件是用react写的,就能够应用react的技术和格调。同样,RN也有函数组件和class组件,特点跟react一样。RN的款式应用StyleSheet.create({})办法,参数是代表款式的对象。当然也能够间接写成对象,不过如同是有一些问题,临时还不分明。RN有一些挪动端应用的官网组件,例如view text button等,跟微信小程序有点像。view组件个别作为容器应用,text就是文本组件,image就是图片组件。另外的组件当前学到再说。以前学会了react,学会了vue,也学了一点node+express,当初开始学react- native,未来可能还要学习小程序和uniapp(重庆这边uniapp用的还挺多的),还有可能要学koa,活到老学到老,要学的货色好多啊!庄子说“吾生也有涯,而知也无涯。以有涯随无涯,殆已“,可如果不学习,就会被淘汰啊

March 17, 2021 · 1 min · jiezi

关于react-native:reactnative版文字跑马灯

js局部 interface IProps { text: string, style?: object,}interface IState { transformX: any, viewWidth: number, textWidth: number,}const FlexItem = Flex.Item;const Speed = 10000export default class Notice extends React.PureComponent<IProps, IState> { state: IState = { transformX: new Animated.Value(0), viewWidth: 0, textWidth: 0, } constructor (props: IProps) { super(props) } onTextLayout = (event: any) => { const { width } = event.nativeEvent.layout; this.setState({ textWidth: width }) } onViewLayout = (event: any) => { const { width } = event.nativeEvent.layout; this.setState({ viewWidth: width }) } move () { const { viewWidth, textWidth, transformX } = this.state; if (textWidth > viewWidth) { let duration = Speed duration += ((textWidth - viewWidth) / viewWidth) * Speed; transformX.setValue(viewWidth) Animated.timing(transformX, { toValue: -textWidth, duration: duration, easing: Easing.linear, useNativeDriver: false }).start(({finished}) => { if (finished) { this.move() } }) } } componentDidUpdate () { this.move() } renderContent(text: string) { const { transformX, textWidth } = this.state; return <Animated.View style={[styles.animatedView, { width: textWidth, transform: [{ translateX: transformX }] }]}> <Text numberOfLines={1}> {text} </Text> </Animated.View> } render() { const { text, style = {} } = this.props; return <View onLayout={this.onViewLayout} style={[styles.view, style]}> <Flex direction="row"> <FlexItem style={{ flexDirection: 'row' }}> {this.renderContent(text)} </FlexItem> </Flex> <View style={styles.hide}> <Text onLayout={this.onTextLayout} numberOfLines={1} style={[styles.hide]}> {text} </Text> </View> </View> }}css局部 ...

February 23, 2021 · 2 min · jiezi

关于react-native:Mac-ReactNative环境搭建报错解决

首先依照官网下载工具 brew install nodebrew install watchman 应用nrm工具切换淘宝源npx nrm use taobao 如果之后须要切换回官网源应用npx nrm use npmnpm install -g yarn 下载xcode软件 下载cocoapodssudo gem install cocoapods 初始化一个我的项目npx react-native init AwesomeProject 进入我的项目运行我的项目cd AwesomeProjectyarn ios 报错信息如下: 解决办法:1.我的项目下装置pod cd ios npm install 2.关掉模拟器,重新启动cd ..yarn ios

December 23, 2020 · 1 min · jiezi

关于react-native:????深入解析跨端框架的核心技术到底是什么

本文是我在学习多个平台 UI 框架后的一些感触,受精力和技术水平所限,文中定有不足之处,请各位大佬多多指教如果你感觉我的文章对你有帮忙,在珍藏的过程中,肯定要记得点赞和点在看哦,谢谢你,这对我真的很重要????! 一、前端三板斧正式探讨「跨端开发」这个概念前,咱们能够先思考一个问题:对大部分前端工作来说,前端次要干些啥? 我集体认为,无论环境怎么变,前端基本上就是做三件事件: fetch data(数据获取)manage state(状态治理)render page(页面渲染)没了。 兴许有人感觉我说的太全面,其实咱们能够理一理。往近了说,当初常识付费搞的热火朝天,动不动就搞个「XXX 源码解析」,剖析一下这些课程的主题和目录,你就会发现根本都是围绕着这三个方向开展讲的;往远了说,咱们能够剖析一下 Web 前端的倒退历程: 1995 年左右,用 HTTP/1.0 拉取数据,用第一版的 JavaScript 治理几个前端状态,用袒露的 HTML 标签展现页面2005 年左右,用 HTTP/1.1 和 AJAX 拉取数据,用 JavaScript 做做表单画画特效,用 CSS 丑化页面2010 年左右,用 HTTP/1.1 和 AJAX 拉取数据,用 jQuery 操作 DOM 解决前端逻辑,用 CSS 丑化页面2015 年左右,随着 HTML5 规范的推广和浏览器性能的晋升,前端开始进入「学不动了」的时代: 在 fetch data 层面,除了 HTTP/1.1 和 AJAX,HTTPS 来了,HTTP/2 来了,WebSocket 也来了在 manage state 层面,Angular、React 和 Vue 先后呈现,从当初看,React 的状态驱动视图的理念间接影响了 Flutter 和 SwiftUI 的设计在 render page 层面,除了传统的 HTML + CSS,还退出了 CSS3、Canvas 等概念,音视频性能也失去增强最近几年,网络协议趋于稳定,几年内也不会有啥大的变动;国内 React 和 Vue 的位置根本巩固,一堆前端盯着 GitHub 进度条等版本更新;render 层出了不少幺蛾子,好不容易解脱了 IE6,又来了各种小程序,同一套业务逻辑写好几遍不经济也不事实,这时候各种跨端计划就整进去了通过一番剖析,这个三板斧实践看上去曾经有些情理了,咱们顺着这个方向再向底层思考:这三大性能是怎么实现的? ...

November 26, 2020 · 3 min · jiezi

关于react-native:React-Native-优化实践之拆包与预热

本文作者:段家顺背景随着 React Native 技术在业务中宽泛的利用,一些比拟重要的性能也开始采纳 React Native 的技术计划来实现,这就给 React Native 页面的关上速度提出了更高的要求,因为关上速度是影响用户跳出率的重要起因之一。 拆包对于 React Native 关上速度优化,业界比拟通用的计划也就是预热+拆分根底包,缩小容器初始化工夫和根底库加载工夫。对 React Native 进行拆包能够依赖于官网提供的工具进行,然而官网提供的能力是 JS 外部的一个拆分加载,如果咱们须要做容器预热,则无奈应用官网的加载计划,而须要咱们从客户端本来的逻辑中进行革新为多步加载。咱们须要对 React Native 的逻辑进行革新,就须要对 React Native 初始化逻辑有所理解。上图是一个大抵的过程,这里咱们对比拟要害的几个步骤进行简略的阐明。 RCTBridge 在实例化之后,会首先筹备好 JS 运行线程和原生模块。而后会创立一个 JSExcutor ,这个执行器决定了 JS 执行环境是客户端还是近程调试(安卓能够是本人定制的执行器,比方 V8)。加载源码( bundle ),这个依据起源不同可能是从本地加载,也可能通过 url 从远端加载。因为初始化 JS 执行器和代码是并行触发的,这里须要一个栅栏同步两者后果,之后开始将代码放入执行器执行( JS 代码运行)。在此之后,客户端会监听垂直同步信号(该信号的作用是在页面产生变更的时候,须要从新刷新页面)。此时 RootView 收到 JS 加载实现的告诉,开始触发 RunApp 逻辑,该逻辑就是启动前端的 app 注册表中对应的利用。整个流程比拟长,然而分工还是相当明确的,此次拆包革新的中央也十分明确。上图中绿色框内就是咱们此次革新的点,这里从实现简略与以后需要的角度登程,将加载代码设计为串行加载,如果须要进一步优化,加载过程也能够进行并发设计。这里咱们对加载能力进行一次形象,加载一段代码定义为一个SourceLoader,那么一个拆包 bridge 就相当于有一个加载器列表,对应于 bridge 上的属性就非常简单。 @property (nonatomic, strong) NSArray<id<RCTBridgeSourceLoaderProtocol>> *preloadSourceLoaders; // 预加载的加载器- (void)preloadSourceWithCompletion:(void(^)(NSError *error))completion; // 触发预加载加载器@property (nonatomic, strong) NSArray<id<RCTBridgeSourceLoaderProtocol>> *sourceLoaders; // 非预加载加载器- (void)loadSourceWithCompletion:(void(^)(NSError *error))completion; // 触发非预加载器- (void)loadAllSourcesWithCompletion:(void(^)(NSError *error))completion; // 先加载预加载代码,再加载非预加载代码这里有一个须要留神的点是,咱们须要启动一个垂直同步信号监听,为了性能思考,须要在预热容器加载到真正视图的时候能力开启,所以这里对加载器减少一个标记,只有加载到该加载器之后能力开启监听。通过这样的革新,咱们的 React Native 就曾经反对了多包散布加载了。咱们就能够把一些根底性能的 JS 代码打包进利用外部,也缩小一些包大小。 ...

November 12, 2020 · 1 min · jiezi

关于react-native:Native地图与Web融合技术的应用与实践

1. 背景美团打车业务很早就在美团App与点评App中提供了服务入口,并在技术上采纳了H5与Native的混合开发技术。随着业务上线,有用户反馈咱们的地图性能有一些问题,起因是咱们打车地图应用的是Web版的地图(通过腾讯地图JavaScript API),业内同类产品应用的是Native版的地图SDK,Native地图相比Web地图具备人造的性能劣势,所以美团打车地图从首屏地图加载到后续的地图操作体验都有肯定差距。 问题和挑战为了改善打车业务的地图体验,咱们想到的计划是在展现地图的局部应用Native地图,而非地图局部应用H5页面来显示,这样既能追平与竞品的地图性能差距,又能充分发挥H5的开发效率。这种计划乍一看仿佛是传统的Hybrid开发,没什么难度与离奇。比方地图应用事后内置到App中的地图SDK实现,H5与Native的交互应用业界成熟的JSBridge技术。但从打车业务角度来看,因为打车业务有很多性能入口须要沉没在地图之上,如起起点卡片、用户核心入口等,这种沉没性能在技术上并不容易实现,而且还要保障用户触摸动作在沉没元素与地图上产生时,别离派发给各自的事件零碎,Hybrid技术在这方面没有教训能够借鉴。 带着这些挑战,咱们进行一系列的尝试与试验,最终将问题解决并封装出咱们打车业务的地图调用框架,咱们称之为Native地图与Web交融框架(下文简称交融框架)。在这个过程中,咱们总结出了一些教训,心愿能给从事相干钻研的同学带来一些帮忙。 2. 调研基于混合技术开发体系,咱们钻研了市面上大部分H5页面与Native地图的利用场景,次要分为如下两类: H5页面与Native地图别离是2个独立的页面:H5业务逻辑用到地图时候,通过交互技术关上一个新地图页面,在新页面内,Native地图依照传入参数调用对应地图组件,实现业务性能的展现。 H5页面与Native地图位于同一页面内:两者将屏幕宰割为两局部,如下图所示:Native地图位于上半局部,WebView H5页面位于下半局部。 通过剖析后,咱们发现这两种模式都无奈满足打车业务场景的需要,因为目前市面上支流的打车业务场景由4局部形成,如下图所示: 起起点抉择面板:占据页面下半局部,能够高低滑动露出更多内容。地图局部:页面上半局部,显示起起点、线路等地图因素信息。更多菜单:左上角图标,点击后跳转到H5性能菜单页面。广告入口:右上角图标,点击后跳转到H5经营页面。 上文第一类,H5页面与Native地图别离位于两个独立页面中,只能满足局部地图场景的需要,无奈布局为上图H5与地图同框显示的成果。 上文第二类,实现这样的布局须要多个WebView能力实现,存在如下毛病: 下方WebView与上方Native地图是平级的组件,各占屏幕的一半,相互间不存在压盖关系,实现起起点面板高低滑动成果艰难。左上角、右上角的更多菜单,广告入口地位须要新增2个WebView组件能力实现笼罩在地图之上,WebView组件再加载对应H5页面实现上述布局,整个步骤比拟繁琐。多个WebView组件形成的页面布局,因为内存空间不共享,它们之间信息的同步比拟艰难,太多的WebView组件对系统性能也是一种节约。调研论断是:市面上现存技术都无奈满足打车场景的需要。 全新计划的提出基于打车场景的特殊性,咱们做了一个大胆的假如:把页面分为2层,上层是Native地图层,布满屏幕;下层是WebView层,齐全笼罩到Native地图层之上,如下图所示: 咱们冀望的成果是: 点击H5元素时,点击事件会派发给H5 WebView容器解决。点击地图区域时,点击事件会派发给Native地图组件解决。H5与Native地图间的信息交互,可采纳成熟的JSBridge技术实现。具体实现思路有如下几点,参照下图: Native地图位于上层,WebView置于Native地图之上,WebView背景通明,透过WebView能够看到下边的地图。红框区域是下层WebView关上的H5页面元素。减少一个手势音讯散发层,该层会智能判断手势事件落在H5元素还是地图元素中。举例:点击红框区域,音讯会传递到WebView层的H5逻辑解决,点击红框之外的区域,音讯会传递到Native地图层解决(地图挪动、缩放等操作)。H5与Native地图交互应用JSBridge实现。比方在地图中增加一个Marker,H5层业务逻辑收回增加Marker的音讯,H5层通过JSBridge技术将音讯发送到Native地图层,Native地图收到音讯后在地图中增加Marker元素。 为了验证想法是否正确,咱们首先通过Android平台开发出Demo,验证这种分层智能传递音讯的做法是可行的,该计划最大长处是兼顾了H5的开发效率与Native地图的高性能个性,十分合乎美团业务地图场景的需要。为了让想法落地时更标准、更零碎,咱们进行了如下的框架设计。 3. 框架设计3.1 热区数据介绍 先介绍一个“热区数据”的概念,下图(3.2节)在手势散发层存在着音讯分发热区数据局部,下文简称热区数据。热区数据是针对下层WebView的一个概念,只对WebView层无效,对上层Native地图层有效。如果用户点击屏幕事件想让H5来捕捉解决,能够在屏幕区域内设置一个逻辑上的矩形区域,如:[0, 0, 50, 50](上图左上角区域),这个数据被称为热区数据。 咱们通过编写代码逻辑,管制手势音讯散发的策略,如果手势音讯产生在热区数据矩形范畴内,咱们把音讯发送给WebView解决,否则发送给Native地图解决。如上图所示,能够在同一屏幕内设定多个热区,[0, 0, 50, 50]、[430, 0, 50, 50]、[0, 200, 480, 200],热区的格局能够本人定义,咱们这里采纳的基于WebView组件左上角为原点的像素坐标格局:[left, top, width, height]。 3.2 框架图介绍 手势音讯分发给WebView层流程 次要为上图1-->2-->3-->4过程,如下: 用户触摸动作首先被手势散发层捕捉,手势散发层判断用户点击到热区数据范畴内,将音讯散发到WebView H5层解决。WebView H5层收到音讯,对音讯进行解决(比方:在地图中增加一个起点Marker),通过通信桥将消息传递到Native地图层。Native地图层收到音讯,并执行增加Marker操作,实现后返回胜利信息。上述总体流程为:手势散发层-->1-->2-->3-->6-->7。手势音讯分发给Native地图层流程 次要为上图 5-->6-->7过程,如下: 手势散发层捕捉到音讯,发现用户手势与以后热区数据矩形没有交加,于是将获取的音讯散发到Native地图层。如果音讯是拖动操作,则Native地图自动识别拖动地图音讯,实现挪动地图的成果,波及流程为:手势散发层-->5。如果音讯是点击操作,比方咱们想实现点击地图中的Marker,将消息传递给H5解决的性能。实现步骤为咱们当时在增加Marker时减少一个点击事件(Native地图层实现),Marker被点击时Native地图层会派发此事件,事件音讯会通过JSBridge技术从Native地图层传到H5层,最初H5层获取到点击音讯。整个操作流程为:手势散发层-->5-->6-->7。热区数据的动静更新策略 因为打车业务底部的面板高度是可伸缩的,所以底部的热区数据并不是静止不动的,须要思考热区数据也要随着DOM元素的拉伸做同步调整。能够通过在WebView H5层监控DOM的变动,DOM元素发生变化时,获取变动后的DOM元素地位、大小,格式化为热区数据,并更新到音讯分发热区数据局部。因为拉伸动作是一个间断的动画成果,为了高效,咱们只在动画完结的那一刻更新热区数据,两头过渡期不做解决。此整体流程为:2-->3-->4。 4. 点评App中的落地实际4.1 手势散发层要害代码这部分性能须要Native端同学实现,包含iOS与Android。两端别离在启动App时设置三层内容,最上层是手势触摸事件接管层,两头是WebView层(背景设置通明),最上层是Native地图层(如腾讯地图SDK)。用数组记录以后热区数据,当手势散发层有事件产生时,通过Touch事件获取手指地位信息,遍历热区数组判断手指地位是否与热区的矩形相交,如相交则将音讯分发给WebView层,否则分发给Native层。下边是Android与iOS音讯散发要害代码: Android散发层要害代码 @Overridepublic boolean dispatchTouchEvent(MotionEvent event){ if(event.getAction() == MotionEvent.ACTION_DOWN) { // 散发层接管到手势触摸音讯,通过dispatchService类判断手势是否落在热区内,从而确定音讯散发的对象 this.touchHandler = dispatchService.inRegion(event) ? TouchHandler.WebView : TouchHandler.MapView; } // 分发给Native地图层 if(this.touchHandler == TouchHandler.MapView) { return this.mapView.dispatchTouchEvent(event); } // 分发给WebView H5层 return super.dispatchTouchEvent(event);}iOS散发层要害代码 ...

October 30, 2020 · 1 min · jiezi

关于react-native:ReactNative与iOS通信原理解析通信篇

文章首发集体博客: ReactNative与iOS通信原理解析-通信篇 导语:其实本来是想编写一篇 react-native (下文简称 rn) 在 iOS 中如何实现 jsbridge 的文章;置信看过官网文档的同学都分明 rn 和 iOS 通信应用了一个叫RCTBridgeModule的模块去实现;置信大家与我一样,不能知其然不知其所以然;所以决定去翻一番 rn 的源码,一探其 rn 与 iOS 通信的机制。后果随着剖析的深刻发现内容较多;于是编写了 ReactNative 与 iOS 原生通信原理解析-初始化 和 ReactNative 与 iOS 原生通信原理解析-JS 加载及执行篇 两篇 RN 源码剖析文章。本文将在上述两篇文章的根底上,持续深刻了解 RN 与 iOS 原生通信机制。 申明: 本文所应用的 rn 版本为0.63.0。 缘起看过后面一篇ReactNative 与 iOS 原生通信原理解析-JS 加载及执行篇的同学应该曾经分明,在执行实现 js 代码之后,会在 JSIExecutor 中执行 flush 函数;flush 函数中会在首次时对 JS 和 native 进行绑定;在绑定之后 native 就能够调用 JS 函数,实现 native to js 之间的通信。 ...

September 27, 2020 · 7 min · jiezi

关于react-native:用Hooks实现的高性能ReactNative-Swiper组件

Github仓库: https://github.com/Voyzz/reac...NPM仓库: https://www.npmjs.com/package... Hello, folks!???? This is a powerful Swiper hooks component for React Native ✨ 为React Native开发的Swiper Hooks组件???? Welcomes to provide your valuable comments or suggestions by 'Issues' or my contact information ✨ 欢送通过”issues“或我的联系方式,为我提供宝贵意见???????????? Powered by Voyz Shen ✨ Shanghai Jiao Tong University, Ctrip CatalogHow to useDemoPropertiesFunctionsVersions<span id='howtouse'><span> How to useinstallationnpm i react-native-swiper-hooks --saveimportimport Swiper from 'react-native-swiper-hooks'use it...const _renderList = ()=>{ let listData = [ { title:'1', bgColor:'#f00' }, { title:'2', bgColor:'#0f0' }, { title:'3', bgColor:'#00f' }, ] return ( listData.map((item,idx)=>{ return ( <View style={{width:WIDTH,height:300,backgroundColor:item.bgColor,justifyContent: 'center',alignItems: 'center'}} key={idx}> <Text>{item.title}</Text> </View> ) }) )}...<Swiper height={300} autoplay={true} loop={true} showPagination={true} > {_renderList()}</Swiper>...updatenpm update react-native-swiper-hooks<span id='demo'><span> ...

September 21, 2020 · 2 min · jiezi

关于react-native:新版React-Native-混合开发iOS篇

在React Native的利用场景中,有时候一个APP只有局部页面是由React Native实现的,比方:咱们罕用的携程App,它的首页下的很多模块都是由React Native实现的,这种开发模式被称为混合开发。 混合开发的一些其余利用场景: 在原有我的项目中退出RN页面,在RN我的项目中退出原生页面 原生页面中嵌入RN模块 RN页面中嵌入原生模块 Native UI Components以上这些都属于React Native混合开发的领域,那么如何进行React Native混合开发呢? 在这篇文章中我将向大家介绍React Native混合开发的流程,须要把握的技术,以及一些教训技巧,与该文章配套的还有React Native与iOS 混合开发解说的视频教程。 React Native混合开发的教程咱们分为高低两篇,上篇次要介绍如何在现有的Android利用上进行React Native混合开发,下篇次要介绍如何在现有的iOS利用上进行React Native混合开发。 将React Native集成到现有的iOS利用中须要如下几个次要步骤:首先,你须要有一个React Native我的项目;为已存在的iOS利用增加React Native所须要的依赖;创立index.js并增加你的React Native代码;创立一个ViewController来承载React Native,在这个ViewController中创立一个RCTRootView来作为React Native服务的容器;启动React Native的Packager服务,运行利用;(可选)依据须要增加更多React Native的组件;运行、调试、打包、公布利用;升职加薪、迎娶白富美,走向人生巅峰!;创立一个React Native我的项目[](https://www.devio.org/2020/04...在做混合开发之前咱们首先须要创立一个没有Android和iOS模块的React Native我的项目。咱们能够通过两种形式来创立一个这样的React Native我的项目: 通过npm装置react-native的形式增加一个React Native我的项目;通过react-native init来初始化一个React Native我的项目;通过npm装置react-native的形式增加一个React Native我的项目第一步:创立一个名为RNHybrid的目录,而后在该目录下增加一个蕴含如下信息的package.json: { "name": "RNHybrid", "version": "0.0.1", "private": true, "scripts": { "start": "yarn react-native start" } }第二步:在为package.json增加react-native 在该目录下执行: npm install --save react-native 执行完上述命令之后,你会看到如下正告: npm install --save react 至此,一个不含Android和iOS模块的React Native我的项目便创立好了。此过程所遇到的更多问题可查阅:React Native与iOS 混合开发解说的视频教程 ...

September 19, 2020 · 3 min · jiezi

关于react-native:ReactNavigation-5-快速入门

链接: React-Navigation 5 疾速入门

September 9, 2020 · 1 min · jiezi

关于react-native:云音乐-React-Native-体系建设与发展

本文作者:章伟东0.33 历史17 年 3 月份,为了解决商城性能和用户体验问题,云音乐技术团队组建了一只 4 人 ReactNative 开发小分队:我负责 RN 前端开发,安卓和 iOS 两位开发负责在云音乐 App 外面嵌入 RN Native SDK,还有一位 Java 开发来负责部署平台工作。 商城 RN 利用上线后,其余团队示意有趣味尝试,但过后 RN 我的项目开发没有脚手架,我的项目创立通过原始拷贝进行,短少 forweb 反对,RN 预加载只接入了 iOS 一端。 种种原因,导致 RN 开发效率低下,音乐人业务本来有趣味用 RN 来开发新利用,开发到一半改成了 H5。 从 17 年 3 月份到 19 年 9 月份,RN 版本始终为 0.33,外围开发团队人员散失一半,部署平台无人保护,我的项目开发短少脚手架,短少 forweb 反对,一共上线 RN 利用为 2.5 个(商城、音乐人、三元音箱)。 搅动历史工夫滚滚向前,新技术层出不穷。2 年半的工夫对于前端倒退来说,恍如隔世。 如果不出任何意外,RN 技术就会躺在历史的尘埃里,无人问津。这种难堪的场面,直到会员收银台达到率优化我的项目才被突破。 会员收银台页面即下图,是云音乐会员购买页面,重要性显而易见。这个页面最开始是一个 React 服务端渲染开发的 H5 页面。 为了能让用户更加顺利购买会员,进步用户体验和达到率,整个技术团队采纳 web 通用优化技术联合云音乐本身技术设施,花了一个月对这个 H5 页面进行优化,将达到率从 72% 进步到 89%,进步了 17 个百分点。与竞品比拟如下(单位是秒)。 ...

September 2, 2020 · 3 min · jiezi

关于react-native:独家React-Native-版本升级指南

前言React Native 作为一款跨端框架,有一个最让人头疼的问题,那就是版本更新。尤其是遇到大版本更新,JavaScript、iOS 和 Android 三端的配置构建文件都有十分大的变动,有时候三者的配置文件又相互耦合在一起,往往牵一发而动全身。 本文假设 React Native 降级的主导者是前端同学,比拟相熟 javaScript 为主的一套前端构建流程。如果有条件,降级时强烈建议拉上 iOS 和 Android 开发,对于一些琐碎的降级细节,当面沟通远比搜索引擎高效。 提醒:因为每次批改和新增内容都会暗藏文章从新审核,倡议浏览博客原文获得最佳浏览体验???? 浏览博客原文 感觉文章对你有用的话肯定要记得点赞哦 ????,谢谢你,这对我来说真的很重要! 一、磨刀不误砍柴工这部分常识我认为是最重要的,毕竟版本更新是永恒的,操作流程却是不变的。 具体介绍各端构建工具前,咱们抛开各种技术细节,从整个我的项目的生命周期登程,看看大部分产品是怎么做技术布局的: 产品晚期:架构都比较简单,整个我的项目拿个配置文件做配置就好了,配置文件越简略越好,xml、json 就被拿进去用了产品发展期:须要配置的中央变多了,这时候多加几个配置项多加几个参数,尽管有些繁琐,但动态的配置文件还够用产品成熟期:人员扩增代码收缩,动态的配置文件齐全不够用了,为了达到动静配置的目标,往往会引入一门脚本语言或借鉴一套 DSL 来治理相干配置产品早期:一把火烧了重整旗鼓(记得删掉)理清一个技术产品的生命周期后,你就会对日常开发中配置文件有了整体的认知:那些又臭又长的配置项,乌七八糟的兼容写法,毫无美感的 DSL,最神奇的是这些七拼八凑的货色还能把我的项目跑起来,Build 胜利的那一刻你肯定会对这种人类奇观收回由衷的钦佩之情——原来这就叫业余啊! 收一收磅礴的情绪,牢记下面的领导教训,咱们上面开始探讨技术细节。 1.【Web 前端】我的项目配置前端工程化始终是前端外面的热点,尽管始终很热,然而具体实现还是一团糟。集体认为起因次要有两点,一个是前端构建从无到有,相对而言基础薄弱;一个是社区推动,百花齐放的同时又没有统一标准。就拿当初前端的次要配置文件来说: 用 package.json 治理 npm 包用 npm script 实现流程治理,有时候还要把相干脚本塞到 package.json 里用 eslint 进行编码标准,有时候还要写个 .eslintrc.js用 babel 解决语法兼容,有时候还要写个 babel.config.js用 webpack 进行我的项目构建和打包公布......下面只是列出了几个支流配置,不出意外的话,当初你的我的项目里曾经有 5 个配置文件了,在 JavaScript 这个前端万能脚本语言的粘合下,这些配置文件还能够相互援用相互耦合,复杂度搞成这样,开发体验还没有 iOS Android 的一半好。 如果你认为我只是单纯的批评前端那你就了解错了,我想表白的是,这么简单的配置都能搞定,iOS Android 的我的项目配置还不是手到擒来? 2.【iOS】我的项目配置iOS 我的项目次要有两个点:project.pbxproj 和 CocoaPods。这两块儿的常识理解后,降级 RN 就齐全不虚了。 ...

August 26, 2020 · 7 min · jiezi

关于react-native:reactnative中webview的通信桥梁irdRnBridge

背景介绍:前段时间花了一些工夫去钻研react-native中webview的通信机制,理解到当中的原理,正好业务中也遇到了rn中webview内嵌h5的页面,发现尽管rn提供了一套相似js的postmessage机制,但在h5和rn之间的通信中往往仅靠这个机制是很难进步开发效率和升高代码的复杂度。因而基于晋升在rn中开发h5效率的原因下,开发了这个ird-RnBridge。这个库从往年5月份开始构思,设计,而后五月份底实现了v1.0.0,之后在七月份进行了迭代开发,并实现了v1.1.0的功能性版本迭代,足以能反对很多场景的开发和调试。 版本迭代历史 简略介绍:该桥梁次要是实用在react-native和h5之间的通信场景下,并且在rn侧和h5侧各提供了一套不雷同的api办法汇合以便调用。它提供了几个方面的性能: 1) 安全性校验建设桥梁:因为rn的很多原生性能是通过webview提供给h5页面调用,如果不甄别嵌入在webview中的h5页面是否平安,而间接全副提供,这会带来很多安全性的问题。因而rnbridge采取了双重校验形式:首先:h5侧必须调用checkSafety发动建设桥梁的申请,rn会对其发过来的申请进行校验,该校验会交给rn侧解决,如果解决通过,则rnbridge会发送一个token值给到h5侧,以表明桥梁建设胜利;其次:每次h5和rn的通信,都会带上该token值,rnbridge在rn侧会对其进行匹配,不统一会禁止调用。 h5侧: RnBridge.checkSafety({demo: 'demo'}, (data) => { document.getElementById('demo').style.color = 'blue'; console.log('bridge success:', data); RnBridge.getSessionStore(['sat2'], (data) => { const content = document.getElementById('content'); content.innerText = JSON.stringify(data); console.log('data1', data); }) });rn侧: RnBridge.initWebview(this.webview, { checkSafety: (params, send) => { this.veritySafety(params, send); },});veritySafety(params, send) { send({isSuccess: true, result: 'welcome'});}如果不定义checksafeCheck,则rnbridge主动认为是通过,从而主动建设桥梁。 2) rn侧和h5侧互相通信:rn侧能够通过initWebview来注册提供给h5侧调用的api办法汇合,当建设了桥梁之时,rnbridge会将注册在initWebview中的办法名的汇合发送到h5侧,h5侧只须要间接调用invokeRN就能够调用rn侧的办法。同理rn侧也是。 3) 提供方便的调试形式:因为h5内嵌在rn的webview之中,h5内的ajax和console都只能通过vconsole这个插件上看到,调试起来不怎么不便。所以rnbridge提供了debug办法并提供了console和ajax两种模式,能够间接将h5中的ajax和console间接在浏览器上看和调试。 console: ajax: 4) 提供h5侧加载资源的性能参数:webview加载h5以及h5和rn建设桥梁等参数能够通过sendPerformance和sendPerformanceByType来发动,并最终能够在rn层获取到h5的资源性能参数。 加载性能参数: 资源性能参数: 原理介绍:这里大略分享一下rnbridge在桥梁建设和相互通信之间的一些设计原理: 平安校验,建设桥梁: h5调用rn办法: rn调用h5办法: 用处介绍:因为rnbridge在rn侧和h5侧各自都领有一套api办法汇合,所以在调用这些办法之前,须要调用rnbridge的switchMode办法,从而抉择对应的一套api办法汇合; 例如在h5侧: RnBridge.switchMode({mode: 'h5'});此时h5的api汇合就会注入到window.RnBridge之中,因而能够全局范畴内随便调用。 ...

August 22, 2020 · 2 min · jiezi

关于react-native:2020-ReactNative-系列之-reactnativesplashscreen

环境撰写工夫:2020-08-03React Native 版本 :0.63.2Xcode 版本:Version 11.6 (11E708)在 RN 中,增加启动图是十分不便的,咱们能够应用 react-native-splash-screen 来实现此工作 react-native-splash-screen 插件也有点老了,官网文档及其他教程都有一些问题,这里更新一下最新的装置过程 Installyarn add react-native-splash-screenios 装置其实只须要执行一行命令就行,会主动帮咱们增加依赖包,所以官网的增加各种文件就不须要了 cd ios && pod install期待 pod install 执行完结,因为前面 iOS 默认启动页是 LaunchScreen.storyboard,咱们须要设置一下 1. 清空 Launch Screen File 2. 增加 LaunchImage 增加后,把 UI 给你的各种不同的分辨率图片往里面拖就行 3. 批改 Build Settings搜寻框搜寻 Launch Image,疾速定位,双击批改为 LaunchImage 4.批改 AppDelegate.m在 AppDelegate.m 中的头部 #import "RNSplashScreen.h" 批改 AppDelegate.m 中的 didFinishLaunchingWithOptions 办法,在最初增加 [RNSplashScreen show]; iOS 配置完结Android 配置安卓也不须要增加各种包,从新 gradle sync 一下就行 ...

August 3, 2020 · 1 min · jiezi

关于react-native:2020-ReactNative-系列之-reactnativesplashscreen

环境撰写工夫:2020-08-03React Native 版本 :0.63.2Xcode 版本:Version 11.6 (11E708)在 RN 中,增加启动图是十分不便的,咱们能够应用 react-native-splash-screen 来实现此工作 react-native-splash-screen 插件也有点老了,官网文档及其他教程都有一些问题,这里更新一下最新的装置过程 Installyarn add react-native-splash-screenios 装置其实只须要执行一行命令就行,会主动帮咱们增加依赖包,所以官网的增加各种文件就不须要了 cd ios && pod install期待 pod install 执行完结,因为前面 iOS 默认启动页是 LaunchScreen.storyboard,咱们须要设置一下 1. 清空 Launch Screen File 2. 增加 LaunchImage 增加后,把 UI 给你的各种不同的分辨率图片往里面拖就行 3. 批改 Build Settings搜寻框搜寻 Launch Image,疾速定位,双击批改为 LaunchImage 4.批改 AppDelegate.m在 AppDelegate.m 中的头部 #import "RNSplashScreen.h" 批改 AppDelegate.m 中的 didFinishLaunchingWithOptions 办法,在最初增加 [RNSplashScreen show]; iOS 配置完结Android 配置安卓也不须要增加各种包,从新 gradle sync 一下就行 ...

August 3, 2020 · 1 min · jiezi

关于react-native:React-Native-的宝支付组件-uiwreactnativealipay-使用

基于 React Native 的宝领取插件,反对 iOS/Android。实用于商家在 App 利用中集成支付宝领取性能,商家 APP 调用支付宝提供的 SDK,SDK 再调用支付宝 APP 内的领取模块。如果用户已装置支付宝APP,商家APP会跳转到支付宝中实现领取,领取完后跳回到商家 APP 内,最初展现领取后果。如果用户没有装置支付宝 APP,商家 APP 内会调起支付宝网页领取收银台,用户登录支付宝账户,领取完后展现领取后果。残缺实例 Example | 残缺的接口文档 注意事项Android:反对2.3及以上的零碎版本运行。iOS:iOS 6.0以上(蕴含iOS 6.0)。反对手机零碎:iOS(苹果)、Android(安卓)。调试请留神 支付宝接入利用必须 已审核通过 状态。支付宝开放平台-管理中心,签约 APP领取 和 APP支付宝登录 性能。实用于 react-native >= 0.60+ 低版本未测试。AlipaySDK 15.7.7 已更新到最新的支付宝 SDK 版本。装置依赖yarn add @uiw/react-native-alipay# react-native version >= 0.60+$ cd ios && pod installAPIAlipay.alipay 领取Alipay.alipay: (payInfo: string) => Promise<OrderResult>;⚠️ 留神领取胜利返回后果是一个字符串,返回内容⚠️ 支付宝须要设置 Scheme 和 iOS增加原生代码,能力反对领取和回弹商家APP的性能⚠️ 支付宝 管理中心-支付宝开放平台 须要签约 APP领取import Alipay from '@uiw/react-native-alipay';// 设置 支付宝 URL Schemes,要表述他是宇宙唯一性,能够应用 `bundle Identifier`// scheme = `alipay` + `APPID`,`APPID` 为支付宝调配给开发者的利用IDAlipay.setAlipayScheme(scheme);// ⚠️ 目前不可用,设置支付宝沙箱环境,仅 Android 反对// Alipay.setAlipaySandbox(isSandbox);async function aliPay() { // 支付宝端领取 // payInfo 是后盾拼接好的领取参数 // return_url= const payInfo = 'alipay_sdk=alipay-sdk-java-dynamicVersionNo&app_id=2021001172656340&biz_content=%7B%22out_trade_no%22%3A%221111112222222%22%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%221234%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%7D&charset=UTF-8&format=json&method=alipay.trade.app.pay&notify_url=http%3A%2F%2Fane.boshu.ltd%2Fowner%2Fpay%2Fapi%2FownerPay%2Fcallback&sign=oUQmGtkv8mrhJ0YwHl9%2FfxMcoLACWuSFKiMTC4Id8nc%2FZVvDQ6MLQq5hhtEN03Qn1%2BAtzTAaofE8nNixdroxOek2l5YtOAcYcXVYlJIyogN%2B22erN2NpDTWJ7tQTKgYFDJLRiG0DZJaxfADhUUF6UR9kdA8omoXKLDlP17ZPUs5Jr4aKv5HJtH5C53ui7PbmyWYg934L4UDC2F%2F9pPQlRwwDeE1SAaV3HW9Dt83kK52o8%2FlChXdotbFdAvH0d4qYGhpEYU5sepj9xiOMyL9aC4pMXW9INYLLGbvtqtlRchZTAfH5yji6nqqQm9KKMmcVrWdBDLyjFVNpejq1UjbJBw%3D%3D&sign_type=RSA2&timestamp=2020-07-09+12%3A16%3A16&version=1.0'; const resule = await Alipay.alipay(payInfo); console.log('alipay:resule-->>>', resule);}订单详情 payInfo 编码前的数据 ...

July 30, 2020 · 2 min · jiezi

关于react-native:React-Native-的宝支付组件-uiwreactnativealipay-使用

基于 React Native 的宝领取插件,反对 iOS/Android。实用于商家在 App 利用中集成支付宝领取性能,商家 APP 调用支付宝提供的 SDK,SDK 再调用支付宝 APP 内的领取模块。如果用户已装置支付宝APP,商家APP会跳转到支付宝中实现领取,领取完后跳回到商家 APP 内,最初展现领取后果。如果用户没有装置支付宝 APP,商家 APP 内会调起支付宝网页领取收银台,用户登录支付宝账户,领取完后展现领取后果。残缺实例 Example | 残缺的接口文档 注意事项Android:反对2.3及以上的零碎版本运行。iOS:iOS 6.0以上(蕴含iOS 6.0)。反对手机零碎:iOS(苹果)、Android(安卓)。调试请留神 支付宝接入利用必须 已审核通过 状态。支付宝开放平台-管理中心,签约 APP领取 和 APP支付宝登录 性能。实用于 react-native >= 0.60+ 低版本未测试。AlipaySDK 15.7.7 已更新到最新的支付宝 SDK 版本。装置依赖yarn add @uiw/react-native-alipay# react-native version >= 0.60+$ cd ios && pod installAPIAlipay.alipay 领取Alipay.alipay: (payInfo: string) => Promise<OrderResult>;⚠️ 留神领取胜利返回后果是一个字符串,返回内容⚠️ 支付宝须要设置 Scheme 和 iOS增加原生代码,能力反对领取和回弹商家APP的性能⚠️ 支付宝 管理中心-支付宝开放平台 须要签约 APP领取import Alipay from '@uiw/react-native-alipay';// 设置 支付宝 URL Schemes,要表述他是宇宙唯一性,能够应用 `bundle Identifier`// scheme = `alipay` + `APPID`,`APPID` 为支付宝调配给开发者的利用IDAlipay.setAlipayScheme(scheme);// ⚠️ 目前不可用,设置支付宝沙箱环境,仅 Android 反对// Alipay.setAlipaySandbox(isSandbox);async function aliPay() { // 支付宝端领取 // payInfo 是后盾拼接好的领取参数 // return_url= const payInfo = 'alipay_sdk=alipay-sdk-java-dynamicVersionNo&app_id=2021001172656340&biz_content=%7B%22out_trade_no%22%3A%221111112222222%22%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%221234%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%7D&charset=UTF-8&format=json&method=alipay.trade.app.pay&notify_url=http%3A%2F%2Fane.boshu.ltd%2Fowner%2Fpay%2Fapi%2FownerPay%2Fcallback&sign=oUQmGtkv8mrhJ0YwHl9%2FfxMcoLACWuSFKiMTC4Id8nc%2FZVvDQ6MLQq5hhtEN03Qn1%2BAtzTAaofE8nNixdroxOek2l5YtOAcYcXVYlJIyogN%2B22erN2NpDTWJ7tQTKgYFDJLRiG0DZJaxfADhUUF6UR9kdA8omoXKLDlP17ZPUs5Jr4aKv5HJtH5C53ui7PbmyWYg934L4UDC2F%2F9pPQlRwwDeE1SAaV3HW9Dt83kK52o8%2FlChXdotbFdAvH0d4qYGhpEYU5sepj9xiOMyL9aC4pMXW9INYLLGbvtqtlRchZTAfH5yji6nqqQm9KKMmcVrWdBDLyjFVNpejq1UjbJBw%3D%3D&sign_type=RSA2&timestamp=2020-07-09+12%3A16%3A16&version=1.0'; const resule = await Alipay.alipay(payInfo); console.log('alipay:resule-->>>', resule);}订单详情 payInfo 编码前的数据 ...

July 30, 2020 · 2 min · jiezi

关于react-native:React-Native-实现自定义下拉刷新组件

本文作者:李磊背景Web 利用如果要更新列表数据,个别会抉择点击左上角刷新按钮,或应用快捷键 Ctrl+F5,进行页面资源和数据的全量更新。如果页面提供了刷新按钮或是翻页按钮,也能够点击只做数据更新。 但挪动客户端屏幕寸土寸金,无论是加上一个刷新按钮,还是配合越来越少的手机按键来做刷新操作,都不是非常便捷的计划。 于是,在这方寸之间,各种各样的滑动计划和手势计划来触发事件,成了挪动客户端的广泛趋势。在刷新数据方面,挪动端最罕用的计划就是下拉刷新的机制。 什么是下拉刷新?下拉刷新的机制最早是由 Loren Brichter 在 Tweetie 2 中实现。Tweetie 是 Twitter 的第三方客户端,起初被 Twitter 收买,Loren Brichter 也成为 Twitter 员工(现已来到)。 Loren Brichter 在 2010 年 4 月 8 日为下拉刷新申请了专利,并取得受权United States Patent: 8448084。但他很违心看到这个机制被其余 app 采纳,也已经说过申请是防御性的。 咱们看下专利爱护范畴最大的主权项是: 在一种安排中,显示蕴含内容项的滚动列表;能够承受与滚动命令相关联的输出;依据滚动命令,显示一个滚动刷新的触发器;基于滚动命令,确定滚动刷新的触发器被激活后,刷新滚动列表中的内容。简略来说,下拉加载的机制蕴含三个状态: “下拉更新”:展现用户下拉可扩大的操作。“松开更新”:提醒用户下拉操作的临界点。“数据更新动画”:手势开释,揭示用户数据正在更新。在那之后,很多以 news feed 为主的挪动客户端都相继采纳了这个设计。 React Native 反对下拉刷新么?React Native 提供了 RefreshControl 组件,能够用在 ScrollView 或 FlatList 外部,为其增加下拉刷新的性能。 RefreshControl 外部实现是别离封装了 iOS 环境下的 UIRefreshControl 和安卓环境下的 AndroidSwipeRefreshLayout,两个都是挪动端的原生组件。 因为适配的原生计划不同,RefreshControl 不反对自定义,只反对一些简略的参数批改,如:刷新指示器色彩、刷新指示器下方字体。并且已有参数还受不同平台的限度。 最常见的需要会要求下拉加载指示器有本人特色的 loading 动画,个别的需求方还会加上操作的文字说明和上次加载的工夫。只反对批改色彩的 RefreshControl 必定是无奈满足的。 ...

July 21, 2020 · 3 min · jiezi

从源码分析可能是全网最实用的React-Native异常解决方案建议收藏

前言在做React Native混合开发时,生产环境有时会遇到关上RN(即React Native简称)利用白屏、RN页面内操作闪退到native页面或者间接导致APP Crash的状况。通过剖析APP日志,发现起因能够归类为一下两种: js 层编译运行时报错。个别是因为某些非凡的数据或情景导致js执行报错;js 转译 native UI 或与 native modules通信时出现异常.对于第一点,能够很快地通过log追踪到呈现问题的js代码并解决,然而对于第二点,往往是框架底层代码执行报错阻塞了UI渲染,报错日志信息无奈定位出哪里出了问题,如: 06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: com.facebook.react.common.c: Error: JS Functions are not convertible to dynamic06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: 06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: This error is located at:06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in RCTView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in RCTView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in RCTView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in u06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in Tile06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in Tile06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in RCTView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in RCTView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in TouchableWithoutFeedback06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in RCTView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in Unknown06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in RCTView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in RCTView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in h06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in RCTView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in RCTScrollView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in u06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in v06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in f06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in RCTView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in RCTView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in h06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in AndroidHorizontalScrollContentView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in AndroidHorizontalScrollView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in u06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in v06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in f06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in RCTView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in n06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in inject-with-store(n)06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in MobXProvider06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in I06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in RCTView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in RCTView06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: in c, stack:06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: <unknown>@-106-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: value@28:222706-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: <unknown>@19:166806-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: Ci@89:6278306-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: qi@89:6667406-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: ea@89:6955506-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: <unknown>@89:8129606-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: unstable_runWithPriority@164:323806-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: ja@89:8125306-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: Oa@89:8100706-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: Wa@89:8031006-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: Aa@89:7932306-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: Ki@89:6862406-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: Ki@-106-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: yt@89:2142006-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: y@115:65706-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: callTimers@115:281606-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: value@28:331106-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: <unknown>@28:82206-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: value@28:256506-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: value@28:79406-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: value@-106-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: at com.facebook.react.modules.core.ExceptionsManagerModule.showOrThrowError(ExceptionsManagerModule.java:54)06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: at com.facebook.react.modules.core.ExceptionsManagerModule.reportFatalException(ExceptionsManagerModule.java:38)06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:372)06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:158)06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method)06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:907)06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:105)06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:29)06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: at android.os.Looper.loop(Looper.java:216)06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:232)06-17 17:59:49.482 10253 24147 24401 E AndroidRuntime: at java.lang.Thread.run(Thread.java:784)利用出现异常还不是最蹩脚的,蹩脚的是因为出现异常,带给了用户蹩脚的体验,只管理论呈现几率非常低。咱们应该在出现异常时,通过降级UI(如web端常见的404页面、"网络开小差了,请稍后再试"弹窗)提醒刺激用户,并疏导用户转向失常页面。很遗憾,通常状况下咱们当初并没有这个主动权,所有异样解决都是由 React Native 框架本人实现的。因而,咱们要从React Native中接管异样解决势力来实现咱们本人的逻辑(相似 反转管制反转 思维) ...

July 9, 2020 · 12 min · jiezi

React-Native中使用reactnativeconfig配置生产开发测试环境

登录https://js.coach/搜索这个安装yarn add react-native-confignpm install react-native-config手动link(见网站上的方法)不需要配置因为会自动link IOS配置(cd ios; pod install)额外的安卓配置这个文件android/app/build.gradle最后面加上 apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"根目录创建.env文件API_URL=https://myapi.com写入这一段 App.js中导入并测试import Config from "react-native-config";const App = () => { return ( <> <StatusBar barStyle="dark-content" /> <SafeAreaView> <ScrollView contentInsetAdjustmentBehavior="automatic" style={styles.scrollView}> <View> <Text>{Config.API_URL}</Text> </View> </ScrollView> </SafeAreaView> </> );};显示API_URL=https://myapi.com配置完毕

July 1, 2020 · 1 min · jiezi

React-Native中绝对路径配置-babelpluginmoduleresolver

安装babelyarn add babel-plugin-module-resolver 配置babel.config.js文件文件会自动在根目录生成配置如下 module.exports = { presets: ['module:metro-react-native-babel-preset'], plugins: [ [ 'module-resolver', { root: ['./src'], //表示哪个目录开始设置绝对路径 alias: { //别名的配置 '@/utils': './src/utils', '@/pages': './src/pages', '@/navigator': './src/navigator', '@/models': './src/models', '@/config': './src/config', '@/components': './src/components', '@/assets': './src/assets', }, }, ], ],};tsconfig.json配置 "baseUrl": "./src" /* Base directory to resolve non-absolute module names. */, "paths": { "@/assets/*": ["assets/*"], "@/components/*": ["components/*"], "@/config/*": ["config/*"], "@/models/*": ["models/*"], "@/navigator/*": ["navigator/*"], "@/pages/*": ["pages/*"], "@/utils/*": ["utils/*"] }完毕自己测试一下能否使用 ...

July 1, 2020 · 1 min · jiezi

react-native

React Native 以下简称RN RN 框架原理将jsx转成js,并解析编译后的js文件,接口通过不同端的bridge,操作native的API。呈现给用户看的是原生的效果。 JSX 源码通过 React Native 框架编译后,通过对应平台的 Bridge 实现了与原生框架的通信。如果我们在程序中调用了 React Native 提供的 API,那么 React Native 框架就通过 Bridge 调用原生框架中的方法。 因为 React Native 的底层为 React 框架,所以如果是 UI 层的变更,那么就映射为虚拟 DOM 后进行 diff 算法,diff 算法计算出变动后的 JSON 映射文件,最终由 Native 层将此 JSON 文件映射渲染到原生 App 的页面元素上,最终实现了在项目中只需要控制 state 以及 props 的变更来引起 iOS 与 Android 平台的 UI 变更。 JavaScript使用JSON将命令异步发送到本机端以进行视图管理。https://hackernoon.com/understanding-react-native-bridge-concept-e9526066ddb8 RN 编译原理与React一样,将jsx转成js,打包到一个js文件中。 RN 运行原理RN需要一个JS的运行环境, 在IOS上直接使用内置的javascriptcore,在Android 则使用webkit.org官方开源的jsc.so。UI方面,与React一样,都是将对应的JSX编译成虚拟DOM,然后通过diff算法,算出变动后的JSON映射文件,最后有Native将JSON文件映射渲染到原生App的页面元素上,最终实现了在项目中只需要控制 state 以及 props 的变更来引起 iOS 与 Android 平台的 UI 变更。在程序中调用原生API,则是通过Bridge,调用Native的API。 ...

June 30, 2020 · 1 min · jiezi

使用-Bob-创建-React-Native-模块并且发布至-NPM

[时间]: 2020/06/25[keyword]: React Native, Guide, 前端, Typescript文章名可能会被误认为是如何开发 RN 的原生模块,这里提醒一下本文主要分享是 bob 的使用过程以及笔者遇到的坑记录前言相比很多小伙伴都和笔者遇到过同样的问题,开发RN模块的流程应该是什么样? 在很久之前 RN CLI 提供了 new-library 的命令,笔者基于这种形式开发了 react-native-uhf-helper react-native-amap-search 两个模块,当时笔者开发前端模块的经验也不充足,稀里糊涂的开发完就没在深入研究了,恰好前不久笔者对一个年久失修的模块进行了重写,也算是有机会再次发布一个 RN 模块,RN 的社区资源还是很完善的,社区组织也是发布了很多高质量的 RN 模块,于是笔者就虽然打开了一个项目(react-native-tab-view)研究其开发方式,经过调查,发现社区的大多数模块都是使用 bob 作为 cli 开发的,于是笔者也正式开始了开发工作。 bob 简介https://github.com/react-nati... bob 集成了 expo、eslint、ESLint、prettier、Typescript 等优秀的 JS 生态来帮助开发者简单的进行 RN 模块的开发。 使用创建模块 npx @react-native-community/bob create react-native-awesome-module添加到已存在的项目,更多请参考 https://github.com/react-nati... yarn add --dev @react-native-community/bobcd yourProject && bob init是的,到此为止你就已经创建了一个用于开发 RN 模块的项目,这个项目已经集成了 ESLint、Typescript ...,通过 yarn prepare 就可以生成用于发布的 .js .d.ts 文件。 发布至 npm发布至 npm 是使用的 release-it, release-it 提供了简单方式来帮助你发布至 npm,管理 change log ...,bob 已经帮我们配置好了,我们只需要执行 ...

June 25, 2020 · 1 min · jiezi

React-Native-与-iOS-OC-之间的交互

前置准备首先最好了解一点关于 oc 的语法知识,不然很多都是看不懂的 创建声明文件 nativeModule.h #import <Foundation/Foundation.h>#import <React/RCTBridgeModule.h>@interface nativeModule : NSObject <RCTBridgeModule>@end创建文件 nativeModule.m #import <Foundation/Foundation.h>#import "nativeModule.h"@interface nativeModule ()@end@implementation nativeModule@end 这是添加完文件后的结构目录 关于 interface 的区别: .h里面的@interface,它是供其它Class调用的。它的@property和functions,都能够被其它Class“看到”(public) 而.m里面的@interface,在OC里叫作Class Extension,是.h文件中@interface的补充。但是.m文件里的@interface,对外是不开放的,只在.m文件里可见(private) 因此,我们将对外开放的方法、变量放到.h文件中,而将不想要对外开放的变量放到.m文件中(.m文件的方法可以不声明,直接用)。 RN 传值给 iOS方法 1 正常传值给原生在 .m 文件中添加方法: // 省略上面的代码@implementation nativeModule// 这句代码是必须的 用来导出 module, 这样才能在 RN 中访问 nativeModule这个 moduleRCT_EXPORT_MODULE();// 接收字符串RCT_EXPORT_METHOD(addHelloWord:(NSString *)name location:(NSString *)location){ NSLog(@"%@,%@", name, location);}@endRN 代码: import { Button, NativeModules } from 'react-native'const { nativeModule } = NativeModules<Button title={'传 2 个参数给 native'} onPress={() => { nativeModule.addHelloWord('你的名字', '位置:浙江')}}/>点击此按钮的作用,就是将 '你的名字', '位置:浙江' 这 2 个字符串传递到了原生端 ...

June 23, 2020 · 3 min · jiezi

reactnative程序使用expo管理打包初探及问题汇总

第一次接触rn,我是想使用rn原生写一个app程序的。然后现实给了我一记响亮的耳光 一开始还蛮顺利的,正常编译,在设备上运行,在我准备引入导航的时候问题出现了,原本正常的程序在使用npm下载react-navigation官网要下载的依赖之后,程序直接报错,经过一番各种百度,可能是版本兼容的问题(但我使用的是最新rn版本0.62.2,react-navigation也是5.x的文档)=。=再加上使用rn文档的打包失败。我对rn失望了。。。是我太菜了,我不配 然后迫不得已使用了expo,真香。推荐使用nrm切换npm源到taobao源 npm i nrm -gnrm use taobao使用npm下载expo-cli工具,创建项目并启动 npm i expo-cli -gexpo init younamecd到项目根目录,使用npm start启动项目。expo会启动本地一个服务,Run on Android device/emulator在安卓手机启动项目。expo会在手机安装一个expo程序,并启动电脑打开的项目。 在expo管理的项目中建议使用expo install安装依赖,expo会自动根据rn版本下载依赖的对应版本,避免兼容性问题(我不就为这个来的嘛)。① 使用expo打包发布应用程序。需要先下载exp工具 npm i exp -g然后配置根目录下的app.json文件,这里可以配置你的app的各种全局参数。②在项目根目录使用exp start启动服务,然后使用exp build:android or exp build:ios来构建你应用程序的二进制文件 ③ 在构建完成时expo会给一个下载链接,打开下载链接,就可以获取到打包好的包了。 遇到的问题汇总: 1) rn版本0.59以上,下载需要的依赖后不在需要react-native link链接项目。但是在使用expo下载后,程序依然会报错,重新启动程序就好了 2) 使用expo init生成的项目会带有app.json文件,但是直接使用会报错,主要将assetBundlePatterns字段值修改为assets/,不然会报错forEach of undefined,添加sdkVersion字段,指定sdk版本,修改ios和android字段,添加包名等内容 3) 如果你是windows用户,那不好意思,这篇文章可能并不能帮你完全构建应用程序安装包,因为按照expo文档,windows构建必须启用WSL,至少启动一次Ubuntu,使用Admin powershell运行: Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux。也就是要在windows开启linux子系统。windows如何启用WSL mac上使用没有此限制,可忽略此步骤。 用到的核心依赖文档:react-navigation导航器 使用expo构建发布你的应用 expo使用文档 附 app.json的基础打包配置: { "expo": { "name": "youname", "slug": "youname", "platforms": [ "ios", "android", "web" ], "version": "1.0.0", "sdkVersion":"37.0.0", "orientation": "portrait", "icon": "./assets/icon.png", "splash": { "image": "./assets/splash.png", "resizeMode": "contain", "backgroundColor": "#ffffff" }, "updates": { "fallbackToCacheTimeout": 0 }, "assetBundlePatterns": [ "assets/" ], "ios": { "bundleIdentifier": "com.youname.youname", "buildNumber": "1.0.0", "supportsTablet": true }, "android": { "package": "com.youname.youname", "versionCode": 1 }, "description": "" }}

May 26, 2020 · 1 min · jiezi

从 1 到完美,用 js 和 react-native 写一个 APP

从 1 到完美,用 js 和 react-native 写一个 APPfacebook 在 2013 年开源了 react 后,紧接着在 2015 年就又开源了 react-native,就此打开了用 js 和前端技术写原生 android&ios APP 之路。尽管到目前为止 react-native 最新版本是 0.56.0,还没有发布正式 1.0 版,但使用 react-native 开发原生 APP 的技术已经比较成熟了,很多商业公司和商业软件都在用 react-native 做开发,比如 facebook, airbnb, uber, skype 等。另外,除了 react 在做写原生 APP 的尝试之外,vue 也在尝试,详见 vue-native。1. 前言开发时建议用 mac,因为 mac 上的 ios 模拟器能在开发时,快速的重载应用,而 android 就慢很多了开发时建议用 yarn, 如果非要用 npm, 务必使用 npm < 5 版本,否则就可能遇到以下的问题(找不到 node_modules 下面的文件):Cannot find entry file node_modules/react-native-scripts/build/bin/crna-entry.jsUnable to resolve “react-navigation” from “App.js"expo xde 中: Metro Bundler failed to start. (code: EMFILE)expo xde 中: Metro Bundler failed to start. (code: EAGAIN)2. 实现原理react-native 在 APP 内启动并维护了一个 js UI 进程(有可能还有 js background 进程),然后把 js UI 进程中的组件及其样式映射到 APP 的原生 UI 层,这样 js UI 进程中组件的更新就立刻反应到 APP UI 进程中,而其他逻辑和数据等的状态都维持在 js UI 进程中。这样便达到了用 js 和前端技术写原生 APP 的功能。 对应 web 来看,react-native 程序只有两个部分,style 和 js,而 js 部分则分为组件和 api。|– react-native |– style 样式部分,对应 web 的 css 部分 |– js 部分 |– 组件 预定义基础容器 |– api 对原生接口的封装2.1 stylereact-native 的 style 用来描述组件的样式、布局等,用 js 书写。它借鉴了 css 的语法,但只支持部分的语法,并且书写方式和实现方式都有很大的不同:没有 class, id 等之类的 css 选择器没有 px, em 等之类的 css 尺寸单位属性名使用 HTML DOM Style 对象 的语法使用样式时只有类似于 css 的行内样式这样的写法比如:import React, { Component } from ‘react’;import { StyleSheet, Text, View } from ‘react-native’;export default class LotsOfStyles extends Component { render() { return ( <View> <Text style={styles.red}>just red</Text> <Text style={styles.bigblue}>just bigblue</Text> <Text style={[styles.bigblue, styles.red]}>bigblue, then red</Text> <Text style={[styles.red, styles.bigblue]}>red, then bigblue</Text> </View> ); }}const styles = StyleSheet.create({ bigblue: { color: ‘blue’, fontWeight: ‘bold’, fontSize: 30, }, red: { color: ‘red’, },});详见 Style, StyleSheet, View Style Props, Text Style Props, Image Style Props2.2 jsreact-native 的 js 与 web 的 js 都是 javascript,这点没区别;但 react-native 的 js 只是纯 js,并不运行在浏览器环境中,也就没有 DOM,一切与 DOM 相关的语法都不可用,如 window, document 等。所以,在 web 端的纯 js 库(无 DOM)在 react-native 中同样适用,如 redux, lodash, immutable-js 等。react-native 的 js 分为组件和接口。组件是由 react-native 定义好的基础容器,就像 html 的标签一样,如 View, Text, Image, WebView 等。接口是 react-native 封装好的原生 APP 的功能,如相机、存储、系统信息等。3. 决定是否使用 react-native尽管 react-native 提供了使用 js 和前端技术写原生 APP 的强大功能,但并不是说就可以用 react-native 代替 java, kotlin 写 android APP、objective-c, swift 写 ios APP 了,它只是提供了一个选择。其实,从上面的实现原理中,基本上可以看出 react-native APP 是有很明显的劣势的:性能不及原生的 APP自由度也不及原来的 APP,因为被约束的 react-native 模式中apk, ipa 文件变大了但 react-native 也有很强大的优势:开发简单、快速,入门坎比较低跨平台,一套代码就可以在多个平台上运行所以,一种不错的选择是:如果追求完美性能和体验的 APP,用原生的方式(androi: java, kotlin, ios: objective-c, swift)开发对性能和体验不敏感,但对人力成本敏感,并且需要快速开发的,用 react-native 开发两者可以混合开发,对性能和体验敏感的用原生的方式开发,对人力成本和时间成本敏感的用 react-native 开发4. 决定使用何种构建方式目前 react-native APP 的构建方式有两种:使用 Android Studio 或 Xcode 开发使用 expo 方式开发4.1 使用 Android Studio 或 Xcode 开发这种方式是目前使用比较多的一种方式,不管是纯 react-native APP 还是混合型 APP(原生与 react-native 混合开发),都是适用的。这种方式的好处是可以进行原生开发、自定义打包,但对大部分前端开发人员来说,这种方式对环境的要求比较高,需要 Android Studio 或 Xcode,并且配置复杂,入门坎很高。初始化# 安装 react-native-clinpm install -g react-native-cli# 新建项目react-native init demo# 切换到项目根目录cd demo开发# 开启本地 js UI 进程服务(开发模式)npm run start# 运行 ios 程序react-native run-ios# 运行 android 程序react-native run-android打包 apk, ipa# 打包 android APP 所需的 js bundle 文件react-native bundle –platform android –dev false –entry-file index.js –bundle-output android/app/src/main/assets/index.android.bundle –assets-dest android/app/src/main/res/ # 打包 apk# 按照正常的 android 打包方式进行# 打包 ios APP 所需的 js bundle 文件react-native bundle –platform ios –dev false –entry-file index.js –bundle-output ios/bundle/index.ios.jsbundle –assets-dest ios/bundle# 打包 ipa# 按照正常的 ios 打包方式进行4.2 使用 expo 方式开发expo 是 facebook 与 expo 合作专门为 react-native 开发的一套工具,它让 react-native 开发从 Android Studio 和 Xcode 中解放出来,使开发者只关注 react-native 开发部分,而不理会复杂的原生开发。这种方式是目前纯 react-native APP 开发的推荐方式。这种方式的好处是不需要 Android Studio 或 Xcode(包括开发和打包),对环境的要求低,配置简单,入门坎低,但不能进行原生开发、自定义打包。初始化# 安装 create-react-native-appnpm install -g create-react-native-app# 新建项目create-react-native-app demo# 切换到项目根目录cd demo或者# 安装 exponpm install -g expo-cli# 新建项目expo init# 切换到项目根目录cd demo开发# 运行 ios 程序npm run ios# 运行 android 程序npm run android或者# 手机上安装 expo 客户端# 开启本地 js UI 进程服务(开发模式)expo start# 运行 ios 程序# 用 expo 客户端扫描二维码# 运行 android 程序# 用 expo 客户端扫描二维码打包 apk, ipa# 打包 apkexpo build:android# 打包 ipaexpo build:ios可能遇到的问题如果构建出错,尝试删除项目根目录下的 .expo 文件夹之后,再试Packager is not running at …: 尝试重新打开一个终端,并尝试删除项目根目录下的 .expo 文件夹之后,再试5. 选择合适的组件库react-navigation: 应用导航组件react-native-elements: UI 组件库NativeBase: UI 组件库react-native-vector-icons: 图标库react-native-swiper: swiper 组件lottie-react-native: airbnb lottie 组件react-native-animatable: 动画组件react-native-scrollable-tab-view: tab 组件6. 选择合适的模板使用 react-native init 或 create-react-native-app 初始化的项目,只是搭建好了基础的骨架,项目的其他部分需要开发者自己去搭建,如 storybook 组件预览、enzyme + jest 测试、eslint + prettier 代码矫正与优化等。所以,选择一个合适的、已经搭建好大部分架子的模板就很受用了:ignite: 内置了 redux、redux-saga、storybook、enzyme、jest、standardsnowflake: 内置了 redux、redux-thunk、jest、eslintpepperoni-app-kit: 用的不多以 ignite 举例:# 安装 ignite-clinpm install -g ignite-cli# 初始化项目ignite new demo# 切换目录cd demo# 现在就可以对项目进行操作了,如添加 screen,运行程序等# 运行 storybook 组件预览npm run storybook# 开启本地 js UI 进程服务(开发模式)npm run start# android 打包npm run android:build# ios 打包需要用 Xcode7. 开发应用除了 style 与 css 的区别和 js 无 DOM 外,其他与开发 web 项目一致。8. 应用实例diary 便是使用 expo 开发的一个日记 APP。9. 后续更多博客,查看 https://github.com/senntyou/blogs作者:深予之 (@senntyou)版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证) ...

September 5, 2018 · 3 min · jiezi

React Native Fetch封装那点事...

每一门语言都离不开网络请求,有自己的一套Networking Api。React Native使用的是Fetch。 今天我们来谈谈与Fetch相关的一些事情。purpose通过这篇文章,你将了解到以下几点关于Fetch的独家报道Fetch的简单运用Fetch的主要ApiFetch使用注意事项Fetch的Promise封装fetchfetch的使用非常简单,只需传入请求的urlfetch(‘https://facebook.github.io/react-native/movies.json');当然是否请求成功与数据的处理,我们还需处理成功与失败的回调function getMoviesFromApiAsync() { return fetch(‘https://facebook.github.io/react-native/movies.json') .then((response) => response.json()) .then((responseJson) => { return responseJson.movies; }) .catch((error) => { console.error(error); });}通过response.json()将请求的返回数据转化成json数据以便使用。通过.then来对数据进行转化处理或最终暴露给调用者;.catch对异常的处理。以上就是一个简单的网络请求,该请求默认是get方式。那么post又该如何请求呢?Api & Note在fetch中我们直接传入url进行请求,其实内部本质是使用了Request对象,只是将url出入到了Request对象中。const myRequest = new Request(‘https://facebook.github.io/react-native/movies.json'); const myURL = myRequest.url; // https://facebook.github.io/react-native/movies.jsonflowers.jpgconst myMethod = myRequest.method; // GET fetch(myRequest) .then(response => response.json()) .then(responseJson => { //todo });如果我们需要请求post,需要改变Request的method属性。fetch(‘https://mywebsite.com/endpoint/', { method: ‘POST’, headers: { Accept: ‘application/json’, ‘Content-Type’: ‘application/json’, }, body: JSON.stringify({ firstParam: ‘yourValue’, secondParam: ‘yourOtherValue’, }),});非常简单,在url后直接传入{}对象,其中指定method使用post。相信大家应该都知道get与post的一个主要区别是get可以在url上直接添加参数,而post为了安全都不采用直接将参数追加到url上,而是使用body来传给service端。在使用body前,这里还需知道headers。下面某个post请求的headers信息需要注意的是Content-Type字段,它代表的是service端接收的数据类型,图片中使用的是application/x-www-form-urlencoded。这对于我们的body来说是非常重要的。只有匹配Content-Type的类型才能正确的传递参数信息。示例的代码使用的是application/json,所以body使用Json.stringify()进行参数转换,而对于Content-Type为application/x-www-form-urlencoded,需要使用queryString.stringify()。Request中除了method、headers与body,还有以下属性Request.cache: 请求的缓存模式(default/reload/no-cache)Request.context: 请求的上下文(audio/image/iframe)Request.credentials: 请求的证书(omit/same-origin/include)Request.destination: 请求的内容描述类型Request.integrity: 请求的 subresource integrityRequest.mode: 请求的模式(cors/no-cors/same-origin/navigate)Request.redirect: 请求的重定向方式(follow/error/manual)Request.referrer: 请求的来源(client)Request.referrerPolicy: 请求的来源政策(no-referrer)Request.bodyUsed: 声明body是否使用在response中请求成功之后,使用.then来转换数据,使用最多的是Body.json(),当然你也可以使用以下的几种数据转换类型Body.arrayBufferBody.blobBody.formDataBody.text以上是fetch请求相关的属性与方法。如果你已经有所了解,那么恭喜你对fetch的基本使用已经过关了,下面对fetch的使用进行封装。封装在实际开发中,url的host都是相同的,不同的是请求的方法名与参数。而对于不同的环境(debug|release)请求的方式也可能不同。例如:在debug环境中为了方便调试查看请求的参数是否正确,我们会使用get来进行请求。所以在封装之前要明确什么是不变的,什么是变化的,成功与失败的响应处理。经过上面的分析,罗列一下封装需要做的事情。不变的: host,headers,body.json()变化的: url,method,body响应方式: Promise(resolve/reject)function convertUrl(url, params) { let realUrl = ApiModule.isDebug? url + “?” + queryString.stringify(Object.assign({}, params, commonParams)) : url; if (ApiModule.isDebug) { console.log(“request: " + realUrl); } return realUrl;}首先对url与参数params进行拼接,如果为debug模式将params拼接到url后。这里使用到了Object.assign()将params与commonParams组合成一个{}对象。最终通过queryString.stringify转化成string。ApiModule.isDebug是原生传递过来的值,对于Android/IOS只需传递自己的ApiModule即可。function getMethod() { return ApiModule.isDebug? “get”: “post”;}上述提到的get与post的请求时机。const headers = { Accept: ‘application/json’, “Content-Type”: “application/x-www-form-urlencoded;charset=UTF-8”};在headers中Content-Type类型为application/x-www-form-urlencodefunction convertBody(params) { return ApiModule.isDebug? undefined : queryString.stringify(Object.assign({}, params, commonParams));}由于debug模式使用的是get方式,但get规定是不能有body的,所以这里使用了undefined来标识。同时为了匹配headers中的Content-Type,params的转化必须使用queryString.stringify;如果接受的是json,可以使用JSON.stringify。定义完之后fetch对外只需接受params参数即可。async function fetchRequest(params){ let body = convertBody(params); fetch(convertUrl(baseUrl, params),{ method: method, headers: headers, body: body }) .then((response) => response.json()) .then((responseJson) => { //todo success }) .catch((error) => { if (ApiModule.isDebug) { console.error(“request error: " + error); }; //todo error });}fetch的请求封装完成,但我们的成功与失败的状态并没有通知给调用者,所以还需要一个回调机制。Promise是一个异步操作最终完成或者失败的对象。它可以接受两个函数resolve、rejectconst p = new Promise((resolve, reject){ … //success resolve(‘success’) //error reject(’error’)});//usep.then(success => { console.log(success); }, error => { console.log(error) });将fetch请求放入到Promise的异步操作中,这样一旦数据成功返回就调用resolve函数回调给调用者;失败调用reject函数,返回失败信息。而调用者只需使用Promise的.then方法等候数据的回调通知。下面来看下完整的fetch封装。async function fetchRequest(params){ let body = convertBody(params); return new Promise(function(resolve, reject){ fetch(convertUrl(baseUrl, params),{ method: method, headers: headers, body: body }) .then((response) => response.json()) .then((responseJson) => { resolve(responseJson); }) .catch((error) => { if (ApiModule.isDebug) { console.error(“request error: " + error); }; reject(error); }); });}之后对fetch的使用就非常简单了,只需传入需要的参数即可。fetchRequest({method: “goods.getInfo”, goodsId: 27021599158370074}).then(res =>{ this.setState({ shareInfo: res.data.shareInfo });});以上是有关fetch的全部内容,当然在React Native中还有其它的第三方请求库:XMLHttpRequest,同时也支持WebSockets。感兴趣的也可以去了解一下,相信会有不错的收获。精选文章5分钟吃透React Native FlexboxViewDragHelper之手势操作神器tensorflow-梯度下降,有这一篇就足够了七大排序算法总结(java)拉粉环节:感觉不错的可以来一波关注,扫描下方二维码,关注公众号,及时获取最新知识技巧。 ...

August 30, 2018 · 2 min · jiezi

react-native flatlist上拉加载onEndReached不能正确触发的解决办法

问题 在写flatlist复用组件时,调用的时候如果父组件是不定高的组件,会造成组件无法显示 如果父组件样式{flex:1},则会出现下拉方法频繁触发或不正常触发的问题(我这里出现的问题是在列表第6个项目在底部时,缓慢上拉会多次触发flatlist的onEndReached监听) 原因 推测是因为{flex:1}不适合做动态高度组件的父组件样式,会错误的判断高度导致onEndReached多次不正常触发。 解决 可以把列表上方所需的组件做成header属性传入组件当做flatlist的头部组件,这样就可以直接调用封装好的组件。 也可以把父元素的样式设成{height: ‘100%’},这样就可以正确的触发onEndReached监听。

August 27, 2018 · 1 min · jiezi