React Native开发指南-在原生和React Native间通信
通过植入原生应用和原生UI组件两篇文档,我们学习了React Native和原生组件的互相整合。在整合的过程中,我们会需要在两个世界间互相通信。有些方法已经在其他的指南中提到了,这篇文章总结了所有可行的技术。
简介
属性
属性是最简单的跨组件通信。因此我们需要一个方法从原生组件传递属性到React Native或者从React Native到原生组件。
从原生组件传递属性到React Native
NSArray *imageList = @[@"http://foo.com/bar1.png",@"http://foo.com/bar2.png"];NSDictionary *props = @{@"images" : imageList};RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridgemoduleName:@"ImageBrowserApp"initialProperties:props];
'use strict';var React = require('react-native');var {View,Image
} = React;class ImageBrowserApp extends React.Component {renderImage: function(imgURI) {return (<Image source={{uri: imgURI}} />);},render() {return (<View>{this.props.images.map(this.renderImage)}</View>);}
}React.AppRegistry.registerComponent('ImageBrowserApp', () => ImageBrowserApp);
NSArray *imageList = @[@"http://foo.com/bar3.png",@"http://foo.com/bar4.png"];
rootView.appProperties = @{@"images" : imageList};
你可以随时更新属性,但是更新必须在主线程中进行,读取则可以在任何线程中进行。
更新属性时并不能做到只更新一部分属性。我们建议你自己封装一个函数来构造属性。
注意:目前,最顶层的RN组件(即registerComponent方法中调用的那个)的
componentWillReceiveProps
和componentWillUpdateProps
方法在属性更新后不会触发。但是,你可以通过componentWillMount
访问新的属性值。
从React Native传递属性到原生组件
属性的限制
跨语言属性的主要缺点是不支持回调方法,因而无法实现自下而上的数据绑定。设想你有一个小的RN视图,当一个JS动作触发时你想从原生的父视图中移除它。此时你会发现根本做不到,因为信息需要自下而上进行传递。
虽然我们有跨语言回调(参阅这里,但是这些回调函数并不总能满足需求。最主要的问题是它们并不是被设计来当作属性进行传递。这一机制的本意是允许我们从JS触发一个原生动作,然后用JS处理那个动作的处理结果。
其他的跨语言交互(事件和原生模块)
从原生代码调用React Natvie函数(事件)
事件的详细用法在这篇文章中进行了讨论。注意使用事件无法确保执行的时间,因为事件的处理函数是在单独的线程中执行。
事件很强大,它可以不需要引用直接修改React Native组件。但是,当你使用时要注意下面这些陷阱:
- 由于事件可以从各种地方产生,它们可能导致混乱的依赖。
- 事件共享相同的命名空间,因此你可能遇到名字冲突。冲突不会在编写代码时被探测到,因此很难排错。
- 如果你使用了同一个React Native组件的多个引用,然后想在事件中区分它们,name你很可能需要在事件中同时传递一些标识(你可以使用原生视图中的
reactTag
作为标识)。
在React Native中嵌入原生组件时,通常的做法是用原生组件的RCTViewManager作为视图的代理,通过bridge向JS发送事件。这样可以集中在一处调用相关的事件。
从React Native中调用原生方法(原生模块)
原生模块同样可以暴露已有的原生库给JS,地理定位库就是一个现成的例子。
警告:所有原生模块共享同一个命名空间。创建新模块时注意命名冲突。
布局计算流
当集成原生模块和React Natvie时,我们同样需要一个能协同不同的布局系统的办法。这一章节讨论了常见的布局问题,并且提供了解决机制的简单说明。
在React Native中嵌入一个原生组件
这个情况在这篇文章中进行了讨论。基本上,由于所有的原生视图都是UIView
的子集,大多数类型和尺寸属性将和你期望的一样可以使用。
在原生中嵌入一个React Native组件
固定大小的React Native内容
// SomeViewController.m- (void)viewDidLoad
{[...]RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridgemoduleName:appNameinitialProperties:props];rootView.frame = CGMakeRect(0, 0, self.view.width, 200);[self.view addSubview:rootView];
}
弹性大小的React Native
有时候我们需要渲染一些不知道大小的内容。假设尺寸将会在JS中动态指定。我们有两个解决办法。
- 你可以将React Native视图包裹在
ScrollView
中。这样可以保证你的内容总是可以访问,并且不会和原生视图重叠。 - React Native允许你在JS中决定RN应用的尺寸,并且将它传递给宿主视图
RCTRootView
。然后宿主视图将重新布局子视图,保证UI统一。我们通过RCTRootView
的弹性模式来达到目的。
// RCTRootView.htypedef NS_ENUM(NSInteger, RCTRootViewSizeFlexibility) {RCTRootViewSizeFlexibilityNone = 0,RCTRootViewSizeFlexibilityWidth,RCTRootViewSizeFlexibilityHeight,RCTRootViewSizeFlexibilityWidthAndHeight,
};
注意:在JS和原生中都设置弹性尺寸可能导致不确定的行为。比如--不要在设置
RCTRootView
为RCTRootViewSizeFlexibilityWidth
时同时指定最顶层的RN组件宽度可变(使用Flexbox)。
看一个例子。
// FlexibleSizeExampleView.m- (instancetype)initWithFrame:(CGRect)frame
{[...]_rootView = [[RCTRootView alloc] initWithBridge:bridgemoduleName:@"FlexibilityExampleApp"initialProperties:@{}];_rootView.delegate = self;_rootView.sizeFlexibility = RCTRootViewSizeFlexibilityHeight;_rootView.frame = CGRectMake(0, 0, self.frame.size.width, 0);
}#pragma mark - RCTRootViewDelegate
- (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView
{CGRect newFrame = rootView.frame;newFrame.size = rootView.intrinsicSize;rootView.frame = newFrame;
}
在例子中我们使用一个FlexibleSizeExampleView
视图来包含根视图。我们创建了根视图,初始化并且设置了代理。代理将会处理尺寸更新。然后,我们设置根视图的弹性尺寸为RCTRootViewSizeFlexibilityHeight
,意味着rootViewDidChangeIntrinsicSize:
方法将会在每次React Native内容高度变化时进行调用。最后,我们设置根视图的宽度和位置。注意我们也设置了高度,但是并没有效果,因为我们已经将高度设置为根据RN内容进行弹性变化了。
你可以在这里查看完整的例子源代码。
动态改变根视图的弹性模式是可行的。改变根视图的弹性模式将会导致布局的重新计算,并且在重新量出内容尺寸时会调用rootViewDidChangeIntrinsicSize
方法。
注意:React Native布局是通过一个特殊的线程进行计算,而原生UI视图是通过主线程更新。这可能导致短暂的原生端和React Native端的不一致。这是一个已知的问题,我们的团队已经在着手解决不同源的UI同步更新。 注意:除非根视图成为其他视图的子视图,否则React Native不会进行任何的布局计算。如果你想在还没有获得React Native视图的尺寸之前先隐藏视图,请将根视图添加为子视图并且在初始化的时候进行隐藏(使用
UIView
的hidden
属性),然后在代理方法中改变它的可见性。
本文转自React Native中文网:http://reactnative.cn/docs/0.20/communication-ios.html#content
React Native开发指南-在原生和React Native间通信相关推荐
- React Native使用指南-植入原生应用
由于React并没有假设你其余部分的技术栈--它通常只作为MVC模型中的V存在--它也很容易嵌入到一个并非由React Native开发的应用当中.实际上,它可以和常见的许多工具结合,譬如CocoaP ...
- vue和react哪个开发效率高,vue 和 react 哪个前景好
react和vue哪个比较好 vue比较好.VUE是 iOS 和 Android 平台上的一款Vlog社区与编辑工具,允许用户通过简单的操作实现Vlog的拍摄.剪辑.细调.和发布,记录与分享生活. 还 ...
- react项目开发步骤_成为专业React开发人员的31个步骤
react项目开发步骤 我为达到可雇用水平而进行的每个项目和课程. (Every single project and course I took to reach a hireable level. ...
- windows 下配置 react native 开发环境
windows 下配置 react native 开发环境 安装nvm 由于react native 需要使用 NodeJs 4.0以上版本,为了方便切换NodeJs,首先我们需要安装nvm. 你可以 ...
- React项目开发中的数据管理
原文链接:https://blog.csdn.net/hl582567508/article/details/76982756 redux中文文档:http://cn.redux.js.org/ Re ...
- React+Redux开发实录(一)搭建工程脚手架
React+Redux开发实录(一)搭建工程脚手架 React+Redux开发实录(二)React技术栈一览 搭建工程脚手架 准备工作 安装node 安装git 安装一款前端IDE 推荐VSCode, ...
- React.js 开发常见问题
React.js 开发常见问题 我需要为 React.js 雇用专门的开发人员,还是说只要会 JavaScript 的员工就行? 如果你有了一支熟练的 JavaScript 开发团队,那么使用 Rea ...
- React实战开发-----一个有关兰州疫情分析的软件,本人负责前端开发,本博客记录整个开发的流程,供大家参考
目录 前言 react介绍(觉得这些官方介绍啰嗦的直接看个人总结) 一.React的起源和发展 二.React的出发点 三.Recat与传统MVC的关系 四.React高性能的体现:虚拟DOM 五.R ...
- Blazor 组件库开发指南
翻译自 Waqas Anwar 2021年5月21日的文章 <A Developer's Guide To Blazor Component Libraries> [1] Blazor 的 ...
最新文章
- MongoDB增加用户认证:增加用户、删除用户、修改用户密码、读写权限、只读权限...
- C语言经典例4-某一天是这一年的第几天
- 微信小程序 延迟执行
- Amazon S3 功能介绍
- winform 打包
- [deviceone开发]-数据绑定示例
- Linux下的文件系统与目录系统简介
- 通解:HTTP超时,或者require TLS/SSL,亦或者conda install / update/ create Solving environment不停
- POJ2352 Stars
- CVS update常用技巧
- android 如何启动nfc卡模拟模式_用手机模拟小区业主卡,出入更加便捷,免去带卡的烦恼,(限安卓)...
- java BBS论坛
- iOS日常开发之frame和bounds的不同
- Thinkphp5-开启调试模式
- 楼宇控制系统发展过程
- qs与querytring区别
- 那个谷歌的网红扔鸡蛋的题,来看看教科书式的回答
- 搜狗翻译加密原理分析
- 用c语言求最大公约数与最小公倍数
- 安全计算:Avast Home Edition提供免费的病毒防护
热门文章
- 用vb.net实现拖放功能
- Centos6.5硬盘故障修复
- codevs 1052:地鼠游戏
- 单例在多线程中的使用
- 团结就是力量,TeamCola浅谈创业团队腾云驾雾的归国征程
- 【计算机网络复习 数据链路层】3.3.2 差错控制(纠错编码)
- 关于计算机的网络作文,关于网络世界的作文
- 华为p10plus能用鸿蒙吗,华为P10/P10 Plus对比评测:自家兄弟大对决
- 如何卸载mysql server 2005_如何卸载SQL Server 2005
- python狗图像识别_TensorFlow卷积神经网络之使用训练好的模型识别猫狗图片