跳到主要内容

为 React Native 构建 <InputAccessoryView>

·7分钟阅读
Peter Argany
Facebook 软件工程师

动机

三年前,GitHub 上有一个 issue 被提出,要求 React Native 支持输入辅助视图。

在接下来的几年里,这个问题上出现了无数的“+1”,各种变通方法,但 React Native 却没有具体的改变——直到今天。从 iOS 开始,我们正在公开一个 API 用于访问原生输入附件视图,我们很高兴分享我们是如何构建它的。

背景

输入附件视图到底是什么?阅读苹果的开发者文档,我们了解到它是一个自定义视图,当接收器成为第一个响应者时,它可以锚定在系统键盘的顶部。任何继承自UIResponder的都可以将.inputAccessoryView属性重新声明为读写,并在此处管理一个自定义视图。响应者基础结构挂载视图,并使其与系统键盘保持同步。解散键盘的手势,如拖动或点击,在框架级别应用于输入附件视图。这使得我们可以构建具有交互式键盘解散功能的内容,这是像 iMessage 和 WhatsApp 这样的顶级消息应用程序中不可或缺的功能。

将视图锚定到键盘顶部有两种常见用例。第一种是创建键盘工具栏,例如Facebook撰写器背景选择器。

在这种情况下,键盘聚焦在文本输入字段上,输入附件视图用于提供额外的键盘功能。此功能与输入字段的类型相关。在地图应用程序中,它可能是地址建议,或者在文本编辑器中,它可能是富文本格式工具。


在这种情况下,拥有<InputAccessoryView>的 Objective-C UIResponder 应该很清楚。<TextInput>已经成为第一个响应者,在底层这变成了一个UITextViewUITextField实例。

第二种常见情况是固定文本输入

这里,文本输入实际上是输入辅助视图本身的一部分。这通常用于消息应用程序中,用户可以在滚动浏览之前的消息线程时撰写消息。


在这个例子中,谁拥有<InputAccessoryView>?它可以再次是UITextViewUITextField吗?文本输入在输入附件视图内部,这听起来像是一个循环依赖。单独解决这个问题本身就是另一篇博客文章。剧透:所有者是一个通用的UIView子类,我们手动告诉它becomeFirstResponder

API设计

我们现在知道`<InputAccessoryView>`是什么,以及我们想如何使用它。下一步是设计一个对两种用例都适用,并且与现有React Native组件(如`<TextInput>`)良好协作的API。

对于键盘工具栏,有几件事需要考虑:

  1. 我们希望能够将任何通用 React Native 视图层次结构提升到 <InputAccessoryView> 中。
  2. 我们希望这个通用且分离的视图层次结构能够接受触摸并能够操纵应用程序状态。
  3. 我们希望将<InputAccessoryView>链接到特定的<TextInput>
  4. 我们希望能够在多个文本输入之间共享一个<InputAccessoryView>,而无需复制任何代码。

我们可以使用类似于React portals的概念来实现 #1。在这个设计中,我们将 React Native 视图传送到由响应者基础结构管理的UIView层次结构。由于 React Native 视图渲染为 UIViews,这实际上非常简单——我们只需覆盖

- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex

并将所有子视图管道传输到新的 UIView 层次结构。对于 #2,我们为<InputAccessoryView>设置了一个新的RCTTouchHandler。状态更新通过使用常规事件回调来实现。对于 #3 和 #4,我们使用nativeID字段在创建<TextInput>组件期间在原生代码中定位附件视图 UIView 层次结构。此函数使用底层原生文本输入的.inputAccessoryView属性。这样做有效地将<InputAccessoryView>链接到其 ObjC 实现中的<TextInput>

支持粘性文本输入(场景 2)增加了一些额外的限制。对于此设计,输入附件视图具有文本输入作为子级,因此通过 nativeID 链接不是一个选项。相反,我们将通用屏幕外UIView.inputAccessoryView设置为我们的原生<InputAccessoryView>层次结构。通过手动告诉这个通用UIView成为第一个响应者,响应者基础结构就会挂载该层次结构。这个概念在前面提到的博客文章中进行了详细解释。

陷阱

当然,在构建这个API时并非一帆风顺。以下是我们遇到的一些陷阱,以及我们如何修复它们。

构建此 API 的一个初步想法涉及侦听NSNotificationCenter的 UIKeyboardWill(Show/Hide/ChangeFrame) 事件。这种模式在一些开源库中以及 Facebook 应用程序内部的某些部分中使用。不幸的是,UIKeyboardDidChangeFrame事件没有及时调用以在滑动时更新<InputAccessoryView>帧。此外,键盘高度的变化未被这些事件捕获。这会创建一类像这样表现的错误

在 iPhone X 上,文本和表情符号键盘的高度不同。大多数使用键盘事件操作文本输入框的应用程序都必须修复上述错误。我们的解决方案是致力于使用.inputAccessoryView属性,这意味着响应者基础设施会处理此类帧更新。


我们遇到的另一个棘手的 bug 是避免 iPhone X 上的 Home Bar。你可能会想,“苹果开发safeAreaLayoutGuide就是为了这个,这很简单!”我们同样天真。第一个问题是,原生的<InputAccessoryView>实现在它即将出现之前没有窗口可以锚定。没关系,我们可以重写-(BOOL)becomeFirstResponder并在那里强制执行布局约束。遵守这些约束会将附件视图向上推,但又出现了另一个 bug:

输入附件视图成功地避开了 Home Bar,但现在不安全区域后面的内容可见。解决方案在于这个雷达。我将原生的<InputAccessoryView>层次结构包装在一个不符合safeAreaLayoutGuide约束的容器中。原生容器覆盖了不安全区域中的内容,而<InputAccessoryView>则保留在安全区域边界内。


使用示例

这里有一个示例,它构建了一个键盘工具栏按钮来重置<TextInput>状态。

class TextInputAccessoryViewExample extends React.Component<
{},
*,
> {
constructor(props) {
super(props);
this.state = {text: 'Placeholder Text'};
}

render() {
const inputAccessoryViewID = 'inputAccessoryView1';
return (
<View>
<TextInput
style={styles.default}
inputAccessoryViewID={inputAccessoryViewID}
onChangeText={text => this.setState({text})}
value={this.state.text}
/>
<InputAccessoryView nativeID={inputAccessoryViewID}>
<View style={{backgroundColor: 'white'}}>
<Button
onPress={() =>
this.setState({text: 'Placeholder Text'})
}
title="Reset Text"
/>
</View>
</InputAccessoryView>
</View>
);
}
}

固定文本输入的另一个例子可以在仓库中找到。

我何时能使用此功能?

此功能实现的完整提交在此处<InputAccessoryView>将在即将发布的 v0.55.0 版本中提供。

快乐打字 :)

将 AWS 与 React Native 结合使用

·10 分钟阅读
Richard Threlkeld
AWS 移动部门高级技术产品经理

AWS 在科技行业以云服务提供商而闻名。这些服务包括计算、存储和数据库技术,以及完全托管的无服务器产品。AWS 移动团队一直与客户和 JavaScript 生态系统成员密切合作,使云连接的移动和网络应用程序更安全、可扩展且更易于开发和部署。我们从一个完整的入门套件开始,但最近还有一些新的发展。

这篇博客文章将探讨一些对 React 和 React Native 开发者来说有趣的内容:

  • AWS Amplify,一个用于使用云服务的 JavaScript 应用程序的声明式库
  • AWS AppSync,一个具有离线和实时功能的完全托管 GraphQL 服务

AWS Amplify

使用 Create React Native App 和 Expo 等工具可以非常轻松地引导 React Native 应用程序。但是,当您尝试将用例与基础设施服务匹配时,将它们连接到云可能很具有挑战性。例如,您的 React Native 应用程序可能需要上传照片。这些照片是否应该按用户进行保护?这可能意味着您需要某种注册或登录过程。您是想要自己的用户目录还是使用社交媒体提供商?也许您的应用程序还需要在用户登录后调用具有自定义业务逻辑的 API。

为了帮助 JavaScript 开发者解决这些问题,我们发布了一个名为 AWS Amplify 的库。其设计是根据任务的“类别”而非 AWS 特定实现进行划分的。例如,如果您希望用户注册、登录,然后上传私人照片,您只需将AuthStorage类别引入您的应用程序即可

import { Auth } from 'aws-amplify';

Auth.signIn(username, password)
.then(user => console.log(user))
.catch(err => console.log(err));

Auth.confirmSignIn(user, code)
.then(data => console.log(data))
.catch(err => console.log(err));

在上面的代码中,您可以看到 Amplify 帮助您完成的一些常见任务示例,例如使用带有电子邮件或短信的多因素身份验证 (MFA) 代码。目前支持的类别有:

  • Auth: 提供凭证自动化。开箱即用的实现使用 AWS 凭证进行签名,以及来自Amazon Cognito的 OIDC JWT 令牌。支持常见功能,例如 MFA 功能。
  • Analytics:只需一行代码,即可在Amazon Pinpoint中获取经过身份验证或未经身份验证的用户的跟踪。您可以根据需要扩展此功能以实现自定义指标或属性。
  • API:提供与 RESTful API 的安全交互,利用AWS Signature Version 4。API 模块在无服务器基础设施与Amazon API Gateway配合使用时表现出色。
  • 存储:简化了在Amazon S3中上传、下载和列出内容的命令。您还可以轻松地按用户将数据分组为公共或私人内容。
  • 缓存:一个跨 Web 应用程序和 React Native 的 LRU 缓存接口,使用特定于实现的持久性。
  • i18n 和日志:提供国际化和本地化功能,以及调试和日志记录功能。

Amplify 的优点之一是它在为您的特定编程环境设计时编码了“最佳实践”。例如,我们发现与客户和 React Native 开发者合作时,开发过程中为了快速完成任务而采取的捷径会延续到生产堆栈中。这可能会损害可伸缩性或安全性,并强制进行基础设施重构和代码重构。

我们如何帮助开发者避免这种情况的一个例子是AWS Lambda 的无服务器参考架构。这些架构展示了在构建后端时如何一起使用 Amazon API Gateway 和 AWS Lambda 的最佳实践。此模式被编码到 Amplify 的API类别中。您可以使用此模式与多个不同的 REST 端点进行交互,并将标头一直传递到您的 Lambda 函数以实现自定义业务逻辑。我们还发布了一个AWS Mobile CLI,用于使用这些功能引导新的或现有的 React Native 项目。要开始使用,只需通过npm安装,然后按照配置提示操作即可

npm install --global awsmobile-cli
awsmobile configure

另一个特定于移动生态系统的编码最佳实践示例是密码安全性。默认的Auth类别实现利用 Amazon Cognito 用户池进行用户注册和登录。此服务实现了安全远程密码协议,作为在身份验证尝试期间保护用户的一种方式。如果您倾向于通读协议的数学原理,您会注意到在计算密码验证器时必须使用一个大素数,通过原根生成一个组。在 React Native 环境中,JIT 已禁用。这使得此类安全操作的 BigInteger 计算性能较低。为了解决这个问题,我们发布了 Android 和 iOS 中的原生桥接器,您可以将它们链接到您的项目中

npm install --save aws-amplify-react-native
react-native link amazon-cognito-identity-js

我们也很高兴地看到 Expo 团队已将此功能纳入其最新 SDK,因此您无需弹出即可使用 Amplify。

最后,专门针对 React Native(和 React)开发,Amplify 包含高阶组件 (HOC),用于轻松包装功能,例如用于注册和登录您的应用程序

import Amplify, { withAuthenticator } from 'aws-amplify-react-native';
import aws_exports from './aws-exports';

Amplify.configure(aws_exports);

class App extends React.Component {
...
}

export default withAuthenticator(App);

底层组件也以<Authenticator />的形式提供,它让您完全控制自定义 UI。它还为您提供了一些管理用户状态的属性,例如他们是否已登录或正在等待 MFA 确认,以及在状态更改时可以触发的回调。

同样,您会找到可用于不同用例的通用 React 组件。您可以根据需要自定义这些组件,例如,在 `Storage` 模块中显示 Amazon S3 中的所有私有图像。

<S3Album
level="private"
path={path}
filter={(item) => /jpg/i.test(item.path)}/>

您可以通过 props 控制许多组件功能,如前面所示,包括公共或私人存储选项。甚至还具有在用户与某些 UI 组件交互时自动收集分析的功能。

return <S3Album track/>

AWS Amplify 偏爱约定优于配置的开发风格,采用全局初始化例程或类别级别的初始化。最快的入门方法是使用aws-exports 文件。但是,开发人员也可以独立使用该库与现有资源。

欲深入了解其理念并观看完整演示,请查看 AWS re:Invent 的视频。

AWS AppSync

AWS Amplify 发布后不久,我们也发布了AWS AppSync。这是一个功能齐全的 GraphQL 服务,同时支持离线和实时功能。虽然您可以使用不同的客户端编程语言(包括原生 Android 和 iOS)使用 GraphQL,但它在 React Native 开发者中非常流行。这是因为数据模型与单向数据流和组件层次结构非常契合。

AWS AppSync 使您能够连接到您自己的 AWS 账户中的资源,这意味着您拥有并控制您的数据。这是通过使用数据源完成的,该服务支持Amazon DynamoDBAmazon ElasticsearchAWS Lambda。这使您可以在单个 GraphQL API 中将功能(例如 NoSQL 和全文搜索)组合为一个模式。这使您能够混合和匹配数据源。AppSync 服务还可以从模式进行配置,因此如果您不熟悉 AWS 服务,您可以编写 GraphQL SDL,点击一个按钮,然后您就会自动启动并运行。

AWS AppSync 中的实时功能通过GraphQL 订阅与众所周知的事件驱动模式进行控制。由于 AWS AppSync 中的订阅通过 GraphQL 指令在模式上进行控制,并且模式可以使用任何数据源,这意味着您可以从使用 Amazon DynamoDB 和 Amazon Elasticsearch Service 的数据库操作中触发通知,或者从您基础设施的其他部分与 AWS Lambda 触发通知。

与 AWS Amplify 类似,您可以使用 AWS AppSync 在 GraphQL API 上使用企业安全功能。该服务允许您使用 API 密钥快速入门。但是,当您投入生产时,它可以转换为使用 AWS Identity and Access Management (IAM) 或 Amazon Cognito 用户池中的 OIDC 令牌。您可以在解析器级别使用策略控制对类型的访问。您甚至可以使用逻辑检查进行运行时精细访问控制检查,例如检测用户是否是特定数据库资源的所有者。还有关于检查组权限以执行解析器或单个数据库记录访问的功能。

为了帮助 React Native 开发者了解这些技术,AWS AppSync 控制台主页上提供了一个内置的 GraphQL 示例模式,您可以启动它。此示例部署一个 GraphQL 模式,配置数据库表,并自动为您连接查询、突变和订阅。还有一个可运行的AWS AppSync 的 React Native 示例,它利用了此内置模式(以及一个React 示例),使您可以在几分钟内运行客户端和云组件。

使用AWSAppSyncClient入门很简单,它与Apollo Client配合使用。AWSAppSyncClient处理 GraphQL API 的安全和签名、离线功能以及订阅握手和协商过程

import AWSAppSyncClient from "aws-appsync";
import { Rehydrated } from 'aws-appsync-react';
import { AUTH_TYPE } from "aws-appsync/lib/link/auth-link";

const client = new AWSAppSyncClient({
url: awsconfig.graphqlEndpoint,
region: awsconfig.region,
auth: {type: AUTH_TYPE.API_KEY, apiKey: awsconfig.apiKey}
});

AppSync 控制台提供了一个可下载的配置文件,其中包含您的 GraphQL 端点、AWS 区域和 API 密钥。然后您可以将客户端与React Apollo一起使用

const WithProvider = () => (
<ApolloProvider client={client}>
<Rehydrated>
<App />
</Rehydrated>
</ApolloProvider>
);

此时,您可以使用标准的 GraphQL 查询。

query ListEvents {
listEvents{
items{
__typename
id
name
where
when
description
comments{
__typename
items{
__typename
eventId
commentId
content
createdAt
}
nextToken
}
}
}
}

上面的示例展示了一个使用 AppSync 提供的示例应用模式的查询。它不仅展示了与 DynamoDB 的交互,还包括数据分页(包括加密令牌)以及EventsComments之间的类型关系。由于应用程序使用AWSAppSyncClient配置,因此数据会自动离线持久化,并在设备重新连接时进行同步。

您可以在此视频中深入了解其背后的客户端技术和 React Native 演示

反馈

库团队渴望了解这些库和服务对您的作用。他们还希望了解我们还能做些什么,以使您使用云服务进行 React 和 React Native 开发变得更容易。请在 GitHub 上联系 AWS Mobile 团队,了解AWS AmplifyAWS AppSync

在 React Native 中实现 Twitter 的应用加载动画

·12 分钟阅读
Eli White
伊莱·怀特
Meta 软件工程师

Twitter的iOS应用有一个我非常喜欢的加载动画。

应用程序准备好后,Twitter 标志会令人愉悦地展开,露出应用程序。

我想弄清楚如何用 React Native 重现这个加载动画。


为了理解**如何**构建它,我首先必须理解加载动画的不同部分。最容易看出细微之处的方法是放慢速度。

这里有几个主要部分需要我们弄清楚如何构建。

  1. 鸟的缩放。
  2. 随着小鸟长大,下面的应用程序也随之显示
  3. 最后稍微缩小应用程序

我花了很长时间才弄清楚如何制作这个动画。

我最初有一个不正确的假设,即蓝色背景和 Twitter 鸟是应用程序之上的一层,并且随着鸟的增大,它变得透明,露出了下面的应用程序。这种方法行不通,因为 Twitter 鸟变得透明会显示蓝色层,而不是下面的应用程序!

幸运的是,亲爱的读者,您不必经历我同样的沮丧。您将获得这个直接进入精彩部分的教程!


正确的方法

在开始编写代码之前,了解如何分解这一点很重要。为了帮助可视化此效果,我在CodePen中重新创建了它(嵌入在几个段落中),以便您可以交互式地查看不同的层。

这种效果主要有三层。第一层是蓝色背景层。尽管这看起来出现在应用程序的顶部,但它实际上在后面。

然后我们有一个纯白层。最后,在最前面,是我们的应用程序。


此动画的主要诀窍是使用 Twitter 标志作为mask,并遮盖应用程序和白色层。我不会深入探讨遮罩的细节,网上有很多资源用于

在此背景下,遮罩的基本原理是:遮罩的不透明像素显示其遮罩的内容,而透明像素则隐藏其遮罩的内容。

我们使用 Twitter 标志作为遮罩,并让它遮盖两个图层:纯白图层和应用程序图层。

为了显示应用程序,我们将遮罩放大,直到它大于整个屏幕。

在遮罩缩放时,我们逐渐增加应用层的透明度,显示应用并隐藏其后面的纯白色层。为了完成效果,我们将应用层从大于 1 的比例开始,并在动画结束时将其缩放至 1。然后我们隐藏非应用层,因为它们将永远不再可见。

他们说一图胜千言。那么一个交互式可视化价值多少字呢?点击“下一步”按钮浏览动画。显示图层可为您提供侧视图。网格有助于可视化透明图层。

现在,针对 React Native

好的。既然我们已经知道了要构建什么以及动画如何工作,那么我们就可以开始编写代码了——这也是您真正来到这里的原因。

这个谜题的主要部分是MaskedViewIOS,一个核心的React Native组件。

import {MaskedViewIOS} from 'react-native';

<MaskedViewIOS maskElement={<Text>Basic Mask</Text>}>
<View style={{backgroundColor: 'blue'}} />
</MaskedViewIOS>;

MaskedViewIOS接受属性maskElementchildren。子元素被maskElement遮盖。请注意,遮罩不需要是图像,它可以是任何任意视图。上述示例的行为是渲染蓝色视图,但它仅在maskElement中的“Basic Mask”字样处可见。我们只是制作了复杂的蓝色文本。

我们想要做的是渲染我们的蓝色层,然后在顶部渲染我们的带有Twitter标志的遮罩应用程序和白色层。

{
fullScreenBlueLayer;
}
<MaskedViewIOS
style={{flex: 1}}
maskElement={
<View style={styles.centeredFullScreen}>
<Image source={twitterLogo} />
</View>
}>
{fullScreenWhiteLayer}
<View style={{flex: 1}}>
<MyApp />
</View>
</MaskedViewIOS>;

这将为我们提供下面看到的图层。

现在是动画部分

我们拥有了使这能正常工作所需的所有部分,下一步是为它们制作动画。为了让这个动画感觉良好,我们将利用 React Native 的 Animated API。

Animated 允许我们以声明式的方式在 JavaScript 中定义动画。默认情况下,这些动画在 JavaScript 中运行,并告诉原生层每帧进行哪些更改。尽管 JavaScript 会尝试每帧更新动画,但它可能无法足够快地完成,从而导致掉帧(卡顿)。这不是我们想要的!

Animated 具有特殊的行为,允许您在没有此卡顿的情况下获得动画。Animated 有一个名为useNativeDriver的标志,它在动画开始时将您的动画定义从 JavaScript 发送到原生,允许原生端处理动画的更新,而无需每帧都往返于 JavaScript。useNativeDriver的缺点是您只能更新一组特定的属性,主要是transformopacity。您不能使用useNativeDriver来动画背景颜色等,至少目前不能——我们会随着时间的推移添加更多,当然您也可以随时为您的项目所需的属性提交 PR,造福整个社区 😀。

由于我们希望这个动画流畅,我们将在此限制内工作。有关useNativeDriver内部工作原理的更深入了解,请查看我们宣布它的博客文章

分解我们的动画

我们的动画有4个组成部分

  1. 放大鸟,显示应用程序和纯白层
  2. 应用程序淡入
  3. 缩小应用程序
  4. 完成后隐藏白色层和蓝色层

使用 Animated,有两种主要方式定义动画。第一种是使用Animated.timing,它允许您精确地指定动画将运行多长时间,以及一个缓动曲线来平滑运动。另一种方法是使用基于物理的 API,例如Animated.spring。使用Animated.spring,您可以指定弹簧中的摩擦和张力等参数,并让物理来运行您的动画。

我们有多个动画需要同时运行,它们都彼此密切相关。例如,我们希望应用在遮罩中间显示时开始淡入。因为这些动画密切相关,我们将使用Animated.timing和一个单独的Animated.Value

`Animated.Value` 是一个原生值的包装器,Animated 用它来了解动画的状态。通常,您希望一个完整的动画只拥有一个这样的值。大多数使用 Animated 的组件会将该值存储在状态中。

由于我将此动画视为在整个动画的不同时间点发生的步骤,因此我们将Animated.Value的起始值设为0(表示0%完成),结束值设为100(表示100%完成)。

我们的初始组件状态将如下。

state = {
loadingProgress: new Animated.Value(0),
};

当我们准备开始动画时,我们告诉Animated将这个值动画到100。

Animated.timing(this.state.loadingProgress, {
toValue: 100,
duration: 1000,
useNativeDriver: true, // This is important!
}).start();

然后,我尝试粗略估计动画的不同部分以及我希望它们在整个动画的不同阶段所拥有的值。下表列出了动画的不同部分,以及我认为它们在随着时间推移的不同点应该拥有的值。

Twitter 鸟遮罩应该从比例 1 开始,然后它会变小,然后尺寸会迅速增加。因此,在动画进行到 10% 时,它的比例值应该为 0.8,然后在结束时迅速增加到比例 70。说实话,选择 70 是相当随意的,它需要足够大,以至于鸟完全露出屏幕,而 60 就不够大 😀。不过,关于这部分有趣的一点是,数字越大,它看起来增长得越快,因为它必须在相同的时间内到达那里。这个数字经过了一些反复试验才使它与这个标志看起来很好。不同大小的标志/设备将需要不同的结束比例,以确保整个屏幕都被揭示。

应用应该保持不透明一段时间,至少在 Twitter 徽标变小期间。根据官方动画,我希望在鸟开始缩放时开始显示它,并尽快完全显示它。因此,在 15% 时我们开始显示它,在整个动画的 30% 时它完全可见。

应用程序的比例从1.1开始,并在动画结束时缩小到其常规比例。

现在,代码来了。

我们上面所做的本质上是将动画进度百分比的值映射到各个部分的所需值。我们使用 Animated 的.interpolate来实现这一点。我们创建了 3 个不同的样式对象,每个动画部分一个,使用基于this.state.loadingProgress的插值值。

const loadingProgress = this.state.loadingProgress;

const opacityClearToVisible = {
opacity: loadingProgress.interpolate({
inputRange: [0, 15, 30],
outputRange: [0, 0, 1],
extrapolate: 'clamp',
// clamp means when the input is 30-100, output should stay at 1
}),
};

const imageScale = {
transform: [
{
scale: loadingProgress.interpolate({
inputRange: [0, 10, 100],
outputRange: [1, 0.8, 70],
}),
},
],
};

const appScale = {
transform: [
{
scale: loadingProgress.interpolate({
inputRange: [0, 100],
outputRange: [1.1, 1],
}),
},
],
};

现在我们有了这些样式对象,我们可以在渲染帖子前面提到的视图片段时使用它们。请注意,只有Animated.ViewAnimated.TextAnimated.Image能够使用使用Animated.Value的样式对象。

const fullScreenBlueLayer = (
<View style={styles.fullScreenBlueLayer} />
);
const fullScreenWhiteLayer = (
<View style={styles.fullScreenWhiteLayer} />
);

return (
<View style={styles.fullScreen}>
{fullScreenBlueLayer}
<MaskedViewIOS
style={{flex: 1}}
maskElement={
<View style={styles.centeredFullScreen}>
<Animated.Image
style={[styles.maskImageStyle, imageScale]}
source={twitterLogo}
/>
</View>
}>
{fullScreenWhiteLayer}
<Animated.View
style={[opacityClearToVisible, appScale, {flex: 1}]}>
{this.props.children}
</Animated.View>
</MaskedViewIOS>
</View>
);

耶!现在我们的动画片段看起来如我们所愿。现在我们只需清理那些不再需要的蓝色和白色图层。

要知道何时可以清理它们,我们需要知道动画何时完成。幸运的是,我们调用`Animated.timing`的`.start`方法接受一个可选的回调函数,该函数在动画完成时运行。

Animated.timing(this.state.loadingProgress, {
toValue: 100,
duration: 1000,
useNativeDriver: true,
}).start(() => {
this.setState({
animationDone: true,
});
});

现在我们在state中有一个值来判断动画是否完成,我们可以修改我们的蓝色和白色图层来使用它。

const fullScreenBlueLayer = this.state.animationDone ? null : (
<View style={[styles.fullScreenBlueLayer]} />
);
const fullScreenWhiteLayer = this.state.animationDone ? null : (
<View style={[styles.fullScreenWhiteLayer]} />
);

瞧!我们的动画现在正常工作了,并且一旦动画完成,我们就清理了未使用的图层。我们已经构建了Twitter应用程序的加载动画!

等等,我的代码不起作用!

别担心,亲爱的读者。我同样讨厌那些只给出部分代码而不提供完整源代码的指南。

此组件已发布到 npm,并在 GitHub 上命名为react-native-mask-loader。要在手机上试用,它可在 Expo 上获得

更多阅读 / 扩展学习

  1. 这本 gitbook 是一个很好的资源,在阅读 React Native 文档后可以了解更多关于 Animated 的知识。
  2. 实际的 Twitter 动画似乎在蒙版显示接近尾声时加速。尝试修改加载器以使用不同的缓动函数(或弹簧!)来更好地匹配该行为。
  3. 蒙版当前的结束缩放是硬编码的,可能无法在平板电脑上显示整个应用程序。根据屏幕尺寸和图像尺寸计算结束缩放将是一个很棒的 PR。

React Native 月报 #6

·阅读时间:4 分钟

React Native 月度会议仍在如火如荼地进行中!请务必查看此帖子底部的下一届会议通知。

Expo

  • 祝贺Devin AbbottHoussein Djirdeh的“全栈 React Native”书预发布!它通过构建几个小型应用程序来引导您学习 React Native。
  • 发布了reason-react-native-scripts的第一个(实验性)版本,以帮助人们轻松试用ReasonML
  • Expo SDK 24 已发布!它使用React Native 0.51,并包含大量新功能和改进:独立应用程序中的捆绑图像(首次加载无需缓存!)、图像处理 API(裁剪、调整大小、旋转、翻转)、人脸检测 API、新发布渠道功能(为给定渠道设置活动版本并回滚)、用于跟踪独立应用程序构建的 Web 控制台,以及修复了 OpenGL Android 实现和 Android 多任务处理器的长期 bug,仅举几例。
  • 从今年一月开始,我们将为 React Navigation 分配更多资源。我们坚信,仅使用 React 组件和 Animated、react-native-gesture-handler等原生组件构建 React Native 导航是可能且可取的,我们对计划中的一些改进感到非常兴奋。如果您想为社区做出贡献,请查看react-native-mapsreact-native-svg,它们都需要一些帮助!

Infinite Red

Microsoft

  • 已启动拉取请求,将核心 React Native Windows 桥接迁移到 .NET Standard,使其有效地与操作系统无关。希望许多其他 .NET Core 平台能够通过自己的线程模型、JavaScript 运行时和 UIManagers(想想 JavaScriptCore、Xamarin.Mac、Linux Gtk# 和 Samsung Tizen 选项)来扩展该桥接。

Wix

  • 排毒
    • 为了扩展 E2E 测试,我们希望最大程度地缩短 CI 上的时间,我们正在为 Detox 开发并行化支持。
    • 提交了一个 pull request,以支持自定义构建,从而更好地支持 E2E 上的模拟。
  • DetoxInstruments
    • 开发 DetoxInstruments 的杀手级功能被证明是一项非常具有挑战性的任务,在任何给定时间获取 JavaScript 回溯需要自定义 JSCore 实现来支持 JS 线程暂停。在 Wix 应用程序内部测试分析器揭示了关于 JS 线程的有趣见解。
    • 该项目目前尚不稳定,无法广泛使用,但正在积极开发中,我们希望很快宣布。
  • React Native 导航
    • V2 的开发速度大幅提升,到目前为止,我们只有 1 名开发人员投入其 20% 的时间,现在我们有 3 名开发人员全职投入!
  • Android 性能

下一次会议

关于将本次会议重新用于讨论一个单一特定主题(例如导航、将 React Native 模块移入单独的仓库、文档等)已经进行了一些讨论。这样我们觉得可以为 React Native 社区做出最大的贡献。这可能会在下次会议期间举行。请随时发推文,告知您希望看到哪些主题。

React Native 月报 #5

·阅读时间:4 分钟

React Native 月度会议继续进行!让我们看看各团队都在忙些什么。

Callstack

  • 我们一直在开发 React Native CI。最重要的是,我们已经从 Travis 迁移到 Circle,使 React Native 拥有了一个单一、统一的 CI 管道。
  • 我们组织了Hacktoberfest - React Native 版,与与会者一起,我们尝试向开源项目提交了许多拉取请求。
  • 我们继续在Haul上工作。上个月,我们发布了两个新版本,包括 webpack 3 支持。我们计划添加CRNAExpo支持,并致力于更好的 HMR。我们的路线图在问题跟踪器上是公开的。如果您想提出改进建议或提供反馈,请告诉我们!

Expo

  • 发布了Expo SDK 22(使用 React Native 0.49)并更新了CRNA
    • 包括改进的启动屏幕 API、基本的 ARKit 支持、“DeviceMotion”API、iOS11 上的 SFAuthenticationSession 支持以及 更多功能。
  • 您的 Snack 现在可以有多个 JavaScript 文件,并且您只需将图像和其他资产拖放到编辑器中即可上传。
  • react-navigation 贡献代码以添加对 iPhone X 的支持。
  • 当我们使用 Expo 构建大型应用程序时,将注意力集中在粗糙的边缘上。例如
    • 一流支持部署到多个环境:预演、生产和任意渠道。渠道将支持回滚和为给定渠道设置活动版本。如果您想成为早期测试者,请告诉我们,@expo_io
    • 我们还在改进我们的独立应用构建基础设施,并增加了在独立应用构建中捆绑图像和其他非代码资产的支持,同时保留了通过空中更新资产的能力。

Facebook

  • 更好的 RTL 支持
    • 我们正在引入许多方向感知的样式。
      • 位置
        • (左|右)→ (开始|结束)
      • 边距
        • 外边距(左|右) → 外边距(开始|结束)
      • 填充
        • 内边距(左|右) → 内边距(开始|结束)
      • 边框
        • borderTop(Left|Right)Radius → borderTop(Start|End)Radius
        • borderBottom(Left|Right)Radius → borderBottom(Start|End)Radius
        • border(Left|Right)Width → border(Start|End)Width
        • border(Left|Right)Color → border(Start|End)Color
    • 在 RTL 中,“左”和“右”的含义在位置、边距、内边距和边框样式中互换了。在几个月内,我们将取消这种行为,使“左”始终表示“左”,“右”始终表示“右”。破坏性更改隐藏在一个标志下。在您的 React Native 组件中使用I18nManager.swapLeftAndRightInRTL(false)来选择加入它们。
  • 正在为我们的内部原生模块进行Flow类型化,并使用这些类型生成 Java 接口和 ObjC 协议,原生实现必须实现这些接口和协议。我们希望这个代码生成器最早能在明年开源。

Infinite Red

  • 用于帮助 React Native 和其他项目的新开源工具。更多信息请点击此处
  • 正在重构 Ignite 以发布新的样板(代号:Bowser)

Shoutem

  • 改进 Shoutem 的开发流程。我们希望简化从创建应用程序到第一个自定义屏幕的过程,并使其变得非常容易,从而降低新 React Native 开发人员的门槛。准备了一些研讨会来测试新功能。我们还改进了Shoutem CLI以支持新流程。
  • Shoutem UI 获得了一些组件改进和错误修复。我们还检查了与最新 React Native 版本的兼容性。
  • Shoutem 平台获得了一些值得注意的更新,新的集成作为开源扩展项目的一部分提供。我们非常高兴看到其他开发者在 Shoutem 扩展上的积极开发。我们积极联系并提供有关其扩展的建议和指导。

下一次会议

下一次会议定于 2017 年 12 月 6 日星期三举行。如果您对我们如何改进会议成果有任何建议,请随时在 Twitter 上给我发消息。

React Native 月报 #4

·3 分钟阅读
Mike Grabowski
迈克·格拉博夫斯基
CTO 兼 Callstack 联合创始人

React Native 月度会议继续进行!以下是各团队的笔记

Callstack

  • React Native EU结束了。来自 33 个国家的 300 多名参与者访问了弗罗茨瓦夫。演讲可以在YouTube 上找到
  • 会后,我们正慢慢回到开源日程。值得一提的是,我们正在开发react-native-opentok的下一个版本,它修复了大部分现有问题。

GeekyAnts

尝试通过以下方式降低开发人员拥抱 React Native 的门槛

  • React Native EU上宣布了BuilderX.io。BuilderX 是一款直接与 JavaScript 文件(目前仅支持 React Native)配合使用的设计工具,可生成美观、可读且可编辑的代码。
  • 启动了ReactNativeSeed.com,它为您的下一个 React Native 项目提供了一系列样板。它提供了多种选项,包括 TypeScript 和 Flow 用于数据类型,MobX、Redux 和 mobx-state-tree 用于状态管理,以及 CRNA 和纯 React-Native 作为技术栈。

Expo

  • 将很快发布 SDK 21,它增加了对 react-native 0.48.3 的支持,以及 Expo SDK 中的一堆错误修复/可靠性改进/新功能,包括视频录制、新的启动画面 API、对react-native-gesture-handler的支持以及改进的错误处理。
  • 关于react-native-gesture-handlerSoftware MansionKrzysztof Magiera正在继续推动这项工作,我们一直在帮助他进行测试并资助他的一部分开发时间。在 SDK21 中将其集成到 Expo 将允许人们在 Snack 中轻松使用它,因此我们很高兴看到人们能想出什么。
  • 关于:改进错误日志记录/处理——有关日志记录的详细信息(特别是“问题 2”),请参阅此内部 Expo PR 的要点,以及此提交,了解处理导入 npm 标准库模块失败的更改。通过这种方式,React Native 上游有大量机会改进错误消息,我们将继续进行后续的上游 PR。社区参与其中也会很棒。
  • native.directory持续增长,您可以从GitHub 仓库添加您的项目。
  • 访问北美各地的黑客马拉松,包括PennAppsHack The NorthHackMIT,以及即将举行的MHacks

Facebook

  • 正在改进 Android 上的<Text><TextInput>组件。(<TextInput>的原生自动增长;深层嵌套的<Text>组件布局问题;更好的代码结构;性能优化)。
  • 我们仍在寻找愿意协助分类问题和拉取请求的额外贡献者。

Microsoft

  • 发布了 CodePush 的代码签名功能。React Native 开发者现在可以在 CodePush 中签署他们的应用程序包。公告可以在这里找到
  • 正在努力完成 CodePush 与 Mobile Center 的集成。同时也在考虑测试/崩溃集成。

下一次会议

下一次会议定于 2017 年 10 月 10 日星期三举行。由于这只是我们的第四次会议,我们想知道这些笔记对 React Native 社区有什么好处。如果您对我们如何改进会议成果有任何建议,请随时在 Twitter 上给我发消息。

React Native 月报 #3

·阅读时长5分钟
Mike Grabowski
迈克·格拉博夫斯基
CTO 兼 Callstack 联合创始人

React Native 月度会议仍在继续!本月会议时间较短,因为我们的大部分团队都在忙于发货。下个月,我们将在波兰弗罗茨瓦夫参加React Native EU大会。务必抢票,届时现场见!同时,让我们看看我们的团队都在忙些什么。

团队

本次第三次会议,有 5 个团队加入了我们

备注

以下是各团队的备注

Callstack

  • 最近开源了react-native-material-palette。它从图像中提取主要颜色,帮助您创建视觉上引人入胜的应用程序。目前它只支持 Android,但我们正在考虑未来添加对 iOS 的支持。
  • 我们已将 HMR 支持和许多其他很酷的东西加入到 haul 中!查看最新版本。
  • React Native 欧洲大会 2017 即将到来!下个月将是 React Native 和波兰的天下!请务必在这里抢购最后几张票。

Expo

  • Snack上发布了对安装 npm 包的支持。通常的 Expo 限制适用——包不能依赖于 Expo 中尚未包含的自定义原生 API。我们还在努力支持 Snack 中的多个文件和上传资产。Satyajit将在React Native Europe上谈论 Snack。
  • 发布了 SDK20,支持相机、支付、安全存储、磁力计、文件系统下载的暂停/恢复,以及改进的启动/加载屏幕。
  • 继续与Krzysztof合作开发react-native-gesture-handler。请尝试一下,使用 PanResponder 或原生手势识别器重建您以前构建的某些手势,并告诉我们您遇到的任何问题。
  • 正在试验 JSC 调试协议,并处理 Canny 上的一堆功能请求。

Facebook

  • 上个月我们讨论了 GitHub 问题跟踪器的管理,以及我们将尝试改进以解决项目的可维护性问题。
  • 目前,开放问题的数量稳定在 600 个左右,并且似乎还会保持一段时间。在过去的一个月里,我们关闭了 690 个由于缺乏活动(定义为过去 60 天内没有评论)而导致的问题。在这 690 个问题中,有 58 个由于各种原因被重新打开(维护者承诺提供修复,或者贡献者提出了一个很好的理由来保持问题开放)。
  • 我们计划在可预见的未来继续自动关闭过时的问题。我们希望达到这样一种状态:跟踪器中打开的每一个有影响的问题都得到处理,但我们还没有达到。我们需要维护人员提供所有帮助来分类问题,并确保我们不会错过引入回归或引入破坏性更改的问题,特别是那些影响新创建项目的问题。有兴趣提供帮助的人可以使用 Facebook GitHub Bot 来分类问题和拉取请求。新的维护者指南包含有关分类和使用 GitHub Bot 的更多信息。请将自己添加到问题工作组,并鼓励其他活跃的社区成员也这样做!

Microsoft

  • 新的 Skype 应用基于 React Native 构建,以尽可能多地在平台之间共享代码。基于 React Native 的 Skype 应用目前可在 Android 和 iOS 应用商店中获取。
  • 在 React Native 上构建 Skype 应用程序时,我们会向 React Native 发送拉取请求,以解决我们遇到的错误和缺失的功能。到目前为止,我们已经合并了大约 70 个拉取请求
  • React Native 使我们能够通过相同的代码库支持 Android 和 iOS Skype 应用程序。我们还希望使用该代码库来支持 Skype Web 应用程序。为了帮助我们实现这一目标,我们构建并开源了一个基于 React/React Native 的薄层,名为ReactXP。ReactXP 提供了一组跨平台组件,当面向 iOS/Android 时映射到 React Native,当面向 Web 时映射到 react-dom。ReactXP 的目标与另一个名为 React Native for Web 的开源库相似。在ReactXP FAQ中简要描述了这些库方法的不同之处。

Shoutem

  • 我们正在继续努力改进和简化使用 Shoutem 构建应用程序时的开发人员体验。
  • 开始将我们所有的应用程序迁移到 react-navigation,但我们最终推迟了这一进程,直到更稳定的版本发布,或者其中一个原生导航解决方案变得稳定。
  • 将所有扩展和我们大部分开源库(animationthemeui)更新到 React Native 0.47.1。

下一次会议

下一次会议定于 2017 年 9 月 13 日星期三举行。由于这只是我们的第三次会议,我们想知道这些笔记对 React Native 社区有什么好处。如果您对我们如何改进会议成果有任何建议,请随时在 Twitter 上给我发消息。

市场中的 React Native 性能

·6 分钟阅读
Facebook 软件工程师

React Native 在 Facebook 家族的多个应用程序的多个地方使用,包括主 Facebook 应用程序中的顶级选项卡。本文的重点是一个高度可见的产品,即Marketplace。它在十几个国家/地区可用,并允许用户发现其他用户提供的产品和服务。

在 2017 年上半年,通过 Relay 团队、Marketplace 团队、移动 JS 平台团队和 React Native 团队的共同努力,我们将 Android 2010-11 年级设备的 Marketplace 交互时间 (TTI) 缩短了一半。Facebook 历来将这些设备视为低端 Android 设备,它们在任何平台或设备类型上的 TTI 最慢。

典型的 React Native 启动过程如下所示:

免责声明:比例不具代表性,会因 React Native 的配置和使用方式而异。

我们首先初始化 React Native 核心(即“Bridge”),然后运行特定于产品的 JavaScript,它决定了 React Native 将在原生处理时间中渲染哪些原生视图。

一种不同的方法

我们早期犯的一个错误是让Systrace 和 CTScan驱动我们的性能优化工作。这些工具在 2016 年帮助我们发现了许多唾手可得的成果,但我们发现 Systrace 和 CTScan 都不能代表生产环境,也无法模拟实际情况。分解中花费时间的比例通常不正确,有时甚至严重偏离。极端情况下,我们预期只需几毫秒的事情实际上需要数百甚至数千毫秒。尽管如此,CTScan 还是有用的,我们发现它能在三分之一的回归进入生产环境之前捕获它们。

在 Android 上,我们将这些工具的缺点归因于以下事实:1) React Native 是一个多线程框架,2) Marketplace 与新闻动态和其他顶级选项卡等众多复杂视图共存,3) 计算时间差异很大。因此,本学期,我们几乎所有决策和优先级都以生产测量和细分数据为依据。

深入生产监测之路

对生产进行仪器化表面上听起来很简单,但结果却是一个相当复杂的过程。它需要多个迭代周期,每个周期 2-3 周;由于提交到 master、将应用程序推送到 Play 商店以及收集足够的生产样本以对我们的工作充满信心的延迟。每个迭代周期都涉及发现我们的分解是否准确,它们是否具有正确的粒度级别,以及它们是否正确地加起来了整个时间跨度。我们不能依赖 alpha 和 beta 版本,因为它们不代表普通人群。本质上,我们非常细致地构建了一个基于数百万个样本总和的非常准确的生产跟踪。

我们一丝不苟地验证了分解中每一毫秒都正确地累加到其父指标的原因之一是,我们很早就意识到我们的仪器化存在空白。结果表明,我们最初的分解没有考虑到线程跳转导致的停滞。线程跳转本身并不昂贵,但跳转到已经忙于工作的繁忙线程则非常昂贵。我们最终通过在适当的时候散布Thread.sleep()调用来本地重现这些阻塞,并通过以下方式成功修复了它们

  1. 移除对 AsyncTask 的依赖,
  2. 撤销在 UI 线程上强制初始化 ReactContext 和 NativeModules,以及
  3. 消除初始化时测量 ReactRootView 的依赖。

综合来看,消除这些线程阻塞问题将启动时间缩短了25%以上。

生产指标也挑战了我们之前的一些假设。例如,我们过去在启动路径上预加载许多 JavaScript 模块,假设将模块放在一个捆绑包中会降低它们的初始化成本。然而,预加载和共存这些模块的成本远远超过了收益。通过重新配置我们的内联 require 黑名单并从启动路径中删除 JavaScript 模块,我们能够避免加载不必要的模块,例如 Relay Classic(当只需要Relay Modern时)。今天,我们的RUN_JS_BUNDLE分解速度提高了 75% 以上。

我们还通过研究特定产品 Native 模块取得了成功。例如,通过惰性注入 Native 模块的依赖项,我们将该 Native 模块的成本降低了 98%。通过消除 Marketplace 启动与其他产品的竞争,我们减少了等效时间段的启动时间。

最棒的是,其中许多改进都广泛适用于所有使用 React Native 构建的屏幕。

结论

人们认为 React Native 启动性能问题是由于 JavaScript 速度慢或网络时间过长造成的。虽然加快 JavaScript 等速度可以显着降低 TTI,但这些因素对 TTI 的贡献百分比远低于之前的预期。

到目前为止的教训是,度量,度量,再度量!一些成功来自将运行时成本转移到构建时,例如 Relay Modern 和Lazy NativeModules。其他成功来自通过更智能地并行化代码或删除死代码来避免工作。还有一些成功来自 React Native 的大型架构更改,例如清理线程阻塞。性能没有万能的解决方案,长期的性能提升将来自增量式测量和改进。不要让认知偏差影响你的决策。相反,仔细收集和解释生产数据以指导未来的工作。

未来计划

从长远来看,我们希望 Marketplace 的 TTI 能够与使用 Native 构建的类似产品相媲美,并且总的来说,React Native 的性能能够与 Native 性能持平。此外,尽管本半期我们大幅降低了桥接启动成本约 80%,但我们计划通过Prepack和更多构建时处理等项目将 React Native 桥接的成本降至接近零。

React Native 月报 #2

·阅读时长 9 分钟
Tomislav Tenodi
Shoutem 产品经理

React Native 月度会议仍在继续!本次会议,我们有幸邀请到了Infinite Red的成员,他们是Chain React,React Native 大会的幕后主脑。由于这里的大部分人都将在 Chain React 上发表演讲,我们将会议推迟了一周。大会的演讲已在线发布,我鼓励大家查看。那么,让我们看看我们的团队都在忙些什么。

团队

第二次会议,共有9个团队加入我们

备注

以下是各团队的备注

Airbnb

Callstack

  • Mike Grabowski一如既往地管理着 React Native 的每月发布,包括一些已推出的测试版。特别是,正在努力将 v0.43.5 构建发布到 npm,因为它解除了 Windows 用户的障碍!
  • Haul上正在进行缓慢但持续的工作。有一个添加了 HMR 的拉取请求,并且其他改进也已发布。最近有几个行业领导者采用了它。可能计划在该领域开始全职有偿工作。
  • 来自Jest团队的Michał Pierzchała本月加入了 Callstack。他将帮助维护Haul,并可能从事Metro BundlerJest的工作。
  • Satyajit Sahoo 现在和我们在一起了,太棒了!
  • 我们的开源部门即将推出一系列酷炫的东西。特别是,正在努力将 Material Palette API 引入 React Native。计划最终发布我们的原生 iOS 套件,旨在提供 1:1 的原生组件外观和感觉。

Expo

  • 最近推出了Native Directory,旨在帮助发现和评估 React Native 生态系统中的库。问题在于:库很多,难以测试,需要手动应用启发式方法,并且不立即清楚哪些是您应该使用的最好的库。也很难知道某些东西是否与 CRNA/Expo 兼容。因此,Native Directory 试图解决这些问题。查看它,并将您的库添加到其中。库列表在此处。这只是我们的第一次尝试,我们希望它由社区拥有和运营,而不仅仅是 Expo 团队。因此,如果您认为它有价值并希望使其更好,请加入我们!
  • Snack中添加了对使用 Expo SDK 19 安装 npm 包的初步支持。如果您遇到任何问题,请告诉我们,我们仍在解决一些错误。与 Native Directory 一起,这应该可以轻松测试仅具有 JS 依赖项或包含在Expo SDK中的依赖项的库。试一试
  • 发布了 Expo SDK19,其中包含全面改进,我们现在正在使用更新的 Android JSC
  • 正在与Alexander Kotliarskyi一起编写文档指南,其中包含一系列关于如何改善应用程序用户体验的提示。请加入并添加到列表中或帮助编写部分内容!
  • 继续致力于:音频/视频、相机、手势(与 Software Mansion 合作,react-native-gesture-handler)、GL 相机集成,并希望在 SDK20(八月)中首次推出其中一些功能,届时其他方面也将有显著改进。我们才刚刚开始为 Expo 客户端构建后台工作(地理定位、音频、处理通知等)的基础设施。
  • Adam Miskiewicz在模仿UINavigationControllerreact-navigation中的过渡方面取得了不错的进展。在他的推文中查看其早期版本——很快就会发布。另请查看他上游MaskedViewIOS。如果您有能力和愿望为 Android 实现MaskedView,那将非常棒!

Facebook

  • Facebook 正在内部探索在 React Native 内部嵌入原生ComponentKitLitho组件的可能性。
  • 非常欢迎对 React Native 的贡献!如果您想知道如何贡献,“如何贡献”指南描述了我们的开发过程,并列出了发送第一个拉取请求的步骤。还有其他不需要编写代码的贡献方式,例如通过分类问题或更新文档。
    • 撰写本文时,React Native 有635开放问题249开放拉取请求。这让我们的维护人员不堪重负,当内部修复问题时,很难确保相关任务得到更新。
    • 我们不确定在保持社区满意的情况下处理此问题的最佳方法是什么。一些(但并非全部!)选项包括关闭过时问题、赋予更多人管理问题的权限,以及自动关闭不符合问题模板的问题。我们编写了“维护人员的期望”指南,以设定期望并避免意外。如果您对我们如何改进维护人员的体验并确保提出问题和拉取请求的人感受到被倾听和被重视有任何想法,请告诉我们!

GeekyAnts

  • 我们在 Chain React 上演示了与 React Native 文件协同工作的设计工具。许多与会者报名了候补名单。
  • 我们还在研究其他跨平台解决方案,如Google Flutter(即将进行重大比较)、Kotlin NativeApache Weex,以了解其架构差异以及我们可以从中学习什么来提高 React Native 的整体性能。
  • 我们的大部分应用程序都切换到了 react-navigation,这改善了整体性能。
  • 此外,还发布了 NativeBase Market - 一个面向(并由)开发者的 React Native 组件和应用程序市场。

Infinite Red

Microsoft

  • CodePush现已集成到Mobile Center中。现有用户的工作流程不会发生变化。
    • 一些人报告了重复应用程序的问题——他们已经在 Mobile Center 上有一个应用程序。我们正在努力解决这些问题,但是如果您有两个应用程序,请告诉我们,我们可以为您合并它们。
  • Mobile Center 现在支持 CodePush 的推送通知。我们还展示了如何将通知和 CodePush 结合起来用于 A/B 测试应用程序——这是 React Native 架构独有的功能。
  • VS Code 在 ReactNative 上有一个已知的调试问题——扩展的下一个版本将在几天内修复此问题。
  • 由于微软内部还有许多其他团队也在从事 React Native 的工作,我们将在下次会议上努力争取所有团队的更好代表。

Shoutem

  • 完成了使Shoutem上 React Native 开发更容易的过程。您可以在 Shoutem 上开发应用程序时使用所有标准的react-native命令。
  • 我们做了大量工作,试图找出如何最好地进行 React Native 性能分析。大部分文档已经过时,我们将尽最大努力在官方文档上创建拉取请求,或者至少在博客文章中写下我们的一些结论。
  • 我们正在将导航解决方案切换到 react-navigation,因此我们可能很快会有一些反馈。
  • 我们在工具包中发布了一个新的 HTML 组件,它将原始 HTML 转换为 React Native 组件树。

Wix

  • 我们已开始着手向Metro Bundler提交拉取请求,并增加了react-native-repackager的功能。我们已将 react-native-repackager 更新至支持 RN 44(我们生产中使用的版本)。我们将其用于detox的模拟基础设施。
  • 在过去的三个星期里,我们一直在用 detox 测试 Wix 应用程序。这是一次令人惊叹的学习经历,了解如何在这种规模的应用程序(超过 40 名工程师)中减少手动 QA。因此,我们解决了 detox 的几个问题,一个新版本刚刚发布。我很高兴地报告,我们正在践行“零缺陷策略”,到目前为止测试一直稳定通过。
  • Detox for Android 进展顺利。我们得到了社区的大力帮助。我们预计在大约两周内推出初始版本。
  • DetoxInstruments,我们的性能测试工具,正在变得比我们最初预期的更大。我们现在计划将其转换为一个独立工具,它将不会与 detox 紧密耦合。它将允许普遍调查 iOS 应用程序的性能。它还将与 detox 集成,以便我们可以对性能指标运行自动化测试。

下一次会议

下一次会议定于 2017 年 8 月 16 日举行。由于这只是我们的第二次会议,我们想知道这些笔记对 React Native 社区有什么好处。如果您对我们如何改进会议成果有任何建议,请随时在 Twitter 上给我发消息。

React Native 月报 #1

·6 分钟阅读
Tomislav Tenodi
Shoutem 产品经理

Shoutem,我们很幸运能从 React Native 的早期就开始使用它。我们决定从第一天起就成为这个神奇社区的一部分。很快,我们意识到要跟上社区成长和改进的速度几乎是不可能的。这就是为什么我们决定组织一个每月一次的会议,所有主要的 React Native 贡献者都可以在会上简要介绍他们的努力和计划。

每月例会

我们于2017年6月14日举行了每月例会的第一次会议。React Native每月会议的使命简单明了:改进React Native社区。展示团队的努力可以促进团队之间的线下协作。

团队

在第一次会议上,有8个团队加入了我们

我们希望有更多的核心贡献者加入接下来的会议!

备注

由于团队的计划可能会引起更广泛受众的兴趣,我们将在这里,在 React Native 博客上分享它们。所以,它们来了

Airbnb

  • 计划为 ViewAccessibilityInfo 原生模块添加一些 A11y(可访问性)API。
  • 将调查在 Android 上为原生模块添加一些 API,以允许指定它们运行的线程。
  • 一直在调查潜在的初始化性能改进。
  • 一直在调查一些更复杂的打包策略,以便在“unbundle”之上使用。

Callstack

  • 正在研究通过使用 Detox 进行 E2E 测试来改进发布流程。拉取请求应该很快就会合并。
  • 他们一直在开发的 Blob 拉取请求已合并,后续拉取请求即将到来。
  • 在内部项目中增加Haul的采用率,以了解其与Metro Bundler相比的性能。与webpack团队合作,提高多线程性能。
  • 在内部,他们已经建立了一个更好的基础设施来管理开源项目。计划在未来几周内推出更多内容。
  • React Native Europe 会议即将举行,目前还没有特别有趣的内容,但欢迎大家参加!
  • 暂时退出了 react-navigation 一段时间,以调查替代方案(特别是原生导航)。

Expo

Facebook

  • React Native的打包工具现在是Metro Bundler,位于独立的仓库中。伦敦的Metro Bundler团队很高兴能满足社区的需求,提高模块化程度以支持React Native之外的更多用例,并提高对问题和PR的响应速度。
  • 在接下来的几个月里,React Native 团队将致力于完善原始组件的 API。预计在布局怪癖、可访问性和流程类型方面会有改进。
  • React Native 团队还计划今年通过重构来改进核心模块化,以完全支持 Windows 和 macOS 等第三方平台。

GeekyAnts

  • 团队正在开发一款 UI/UX 设计应用程序(代号:Builder),它直接处理 .js 文件。目前,它只支持 React Native。它类似于 Adobe XD 和 Sketch。
  • 团队正在努力工作,以便您可以在编辑器中加载现有的 React Native 应用程序,进行更改(以设计师的视角进行视觉更改),并将更改直接保存到 JS 文件中。
  • 大家正在努力弥合设计师和开发者之间的差距,并将他们带到同一个代码仓库中。
  • 此外,NativeBase 最近达到了 5,000 个 GitHub 星。

Microsoft

  • CodePush现已集成到Mobile Center中。这是提供与分发、分析和其他服务更紧密集成体验的第一步。请参阅他们的公告此处
  • VS Code 在调试方面存在一个 bug,他们正在努力修复,并将发布新的构建版本。
  • 正在研究 Detox 进行集成测试,并研究 JSC Context 以获取变量和崩溃报告。

Shoutem

  • 通过React Native社区的工具,使Shoutem应用的开发变得更容易。您将能够使用所有React Native命令来运行在Shoutem上创建的应用。
  • 正在研究 React Native 的性能分析工具。他们在设置时遇到了很多问题,并将撰写他们在此过程中发现的一些见解。
  • Shoutem 正在努力使 React Native 与现有原生应用程序的集成变得更容易。他们将记录公司内部开发的概念,以获取社区的反馈。

Wix

  • Wix正在内部采用Detox,以将Wix应用的很大一部分迁移到“零人工质量保证”。因此,Detox正在被数十名开发人员在生产环境中大量使用,并迅速成熟。
  • 正在努力为Metro Bundler添加支持,以便在构建期间覆盖任何文件扩展名。它将支持任何自定义扩展名,如“e2e”或“detox”,而不仅仅是“ios”和“android”。计划将其用于E2E模拟。已经有一个名为react-native-repackager的库,现在正在处理PR。
  • 正在研究性能测试自动化。这是一个名为 DetoxInstruments 的新仓库。您可以查看一下,它正在开源开发中。
  • 与 KPN 的一位贡献者合作,开发适用于 Android 的 Detox 并支持真实设备。
  • 正在考虑将“Detox作为平台”,以允许构建需要自动化模拟器/设备的其他工具。一个例子是适用于React Native的Storybook或Ram关于集成测试的想法。

下一次会议

会议将每四周举行一次。下次会议定于2017年7月12日。由于我们刚开始召开这个会议,我们想知道这些笔记如何有益于React Native社区。如果您对我们下次会议应涵盖的内容或如何改进会议输出有任何建议,请随时在Twitter上联系我