React-Native实践

随着React-Native的火爆,以及Native和Web开发本身的一些痛点,近期团队考虑将iOS App中部分界面迁移到React-Native上,本文主要谈谈开发过程中遇到的一些问题及解决方案。

图片路径

图片来源有2种:local 和 remote。

remote 图片

remote图片是通过http请求来处理的。

<Image source={{url:'http://10.url.cn/xx.jpg'}}

这种方式的优势:

  • 引入方式简单
  • 更新方便,只需要替换server上的图片即可,不需要修改源代码

缺点很明显:

  • 即初次请求图片时,需要请求server,图片过大的,请求的延时会很大
local 图片

local图片的引入方式有好几种:

  • 以 iOS App资源的方式引入。将图片以资源方式加入 OC 工程中,最终会将资源编译到安装包,更新需要依赖客户端发版本。
  • 图片 base64 引入,更新需要修改代码。
  • 绝对路径,将图片放在App某个目录下,在项目中引用。 // iOS App资源方式 <Image source={ require(image!icon1) } /> // base64 <Image source={{ isStatic: true, url: 'data:image/jpeg;base64,'+ base64 }} /> // absolute path <Image source={{ isStatic: true, url: '/Users/xxx/xxx.jpg' }} />

最终采用了绝对路径的方式,基于以下几点:

  • 图片在本地,加载速度快
  • 替换本地图片即可完成更新

同时,带来了另一个问题:JS中引用图片时,实际只知道图片相对于JS的路径,最终应用安装到哪个路径下是不知道的。解决方式是,通过Native接口,将路径前缀通知到Web,然后由Web将相对路径图片拼接成绝对路径,同时,将这个路径前缀缓存,避免重复调用。

缓存打包方案

facebook提供2种方式集成react-native代码:online 和 offline。对应的OC引入JS的方式:

// online
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle"];
// offline
jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];

online方式走http请求,响应延时大,但更新方便;offline走本地资源方式,将相关资源打入安装包,请求响应快,更新依赖客户端。

最终采用了offline + 离线包方案,将资源打成离线包,放入安装包中。后续有更新时,将离线包上传到离线包管理平台,每次打开React-Native相关界面时,native会发起CGI请求,检查现网是否有最新版本的离线包,如果有,CGI会返回最新的离线包地址,Native下载最新的离线包,解压到本地,下次访问时,即可访问最新的代码。

组件通讯

这里提到的通讯,更多是数据层面的通讯。在实现课程列表页时,点击上面的菜单,下面的课程列表数据要变化。

这是在实现上,是3个组件:页面本身Page,菜单list,课程list。菜单list和课程list被Page引用,两者之间的数据通讯,需要通过Page来传递。

render: function() {
    return (
        <View>
            <CourseList 
                mt={this.state.mt}  
                st={this.state.st} 
                tt={this.state.tt} />
            <CatList onChange={this._setCatsId} />
        </View>
    )
},
_setCatsId: function(name, val) {
// 修改 Page 的state
}

主要通讯逻辑:

  • 在CatList点击某个分类之,调用组件prop属性 onChange方法。
  • onChange是Page组件的一个function,用于修改Page中的state;这样CatList的改变,同步到了Page。
  • CourseList的属性绑定到了Page的state,Page的state变化时,会同步到CourseList的prop。
  • CourseList 生命周期中componentWillReceiveProps会捕获这种变化,将数据的变更逻辑放到这个函数即可实现同步。

接口扩展

JS-OC之间的通讯机制,这里已经写的很清楚了,主要是双方保存了同样一份模块注册表。

在图片加载那里,Native提供了一个获取地址前缀的接口,主要代码片段:

@implementation EduProvidePathToJS
// 注册模块
RCT_EXPORT_MODULE();
// 注册方法,会将方法和模块写入到注册表中。
RCT_EXPORT_METHOD(getPath:(RCTResponseSenderBlock)callback) {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *documentPath  = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *pathToWebappCacheInDocuments = [documentPath stringByAppendingPathComponent:@"webappCache2"];
    callback(@[pathToWebappCacheInDocuments]);
}
@end

JS调用逻辑

// 引入模块
var ProvidePathToJS = require('NativeModules').EduProvidePathToJS;
// 调用方法
ProvidePathToJS.getPath(function(path) {
});

布局相关

React-Native使用了flexbox布局,在居中和等分上有一定的优势。其中,没有“层”的概念,也就是说z-index这货是无效的,默认都在同一层,后面的会覆盖前面的,用这种方式模拟“层”。 另外一些坑:

  • 如果4点的margin不同,不能缩写,需要逐个写,padding同。
  • 没有 之类的,换行使用{'\n'},缩紧text-indent也没有,最开始是在段前用Text标签模拟,后来发现{'\n'}这货后,果断试了{'\t'},居然可以。
  • background-image,本身不支持图片背景,repeat不提了,需要使用Image模拟。

从目前的Css代码迁移到React-Native,感觉有很多适配工作。

最后

9月会跟着iOS的版本,带一部分React-Native的代码到外网,搜集到数据后,后面会在iOS慢慢铺开使用。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Linyb极客之路

前端性能优化-雅虎军规35条

合并图片(如css sprites,内置图片使用数据)、合并CSS、JS,这一点很重要,但是要考虑合并后的文件体积。

1005
来自专栏天天

网页特殊字体过大的优化

==font-spider 仅适用于固定文本,如果文字内容为动态可变的,新增的文字将无法显示为特殊字体。==

1035
来自专栏文大师的新世界

4. Navigation实战

本来想写一个应用redux的Navigation实战,但是发现react-native有又新的更新,新手怕误导大家,就直接用了别人的组件,看看怎么应用吧。本次在...

582
来自专栏AhDung

【C#】注意用“划算”的方式使用图标

先解释一下何谓“划算”:假定一个Winform程序包含若干个窗体,每个窗体左上角都要显示图标(即要设置Form.Icon属性),该程序本身也要有个图标(用于在O...

773
来自专栏守候书阁

webpack+vue项目实战(二,开发管理系统主页面)

上篇文章(webpack+vue项目实战(一,搭建运行环境和相关配置))搭建了好了基本的一个项目目录,安好好了一些要用到的依赖,以及把项目跑了起来。接下来,我们...

391
来自专栏滕先生的博客

react-native 跨平台滤镜集成

3388
来自专栏海天一树

小朋友学Python Web(3):实现点击按纽跳转

793
来自专栏腾讯移动品质中心TMQ的专栏

当 Espresso 遇见 Android 单元测试

如果依赖 Android 环境,但是没有 UI 相关的单元测试可以使用开源库 Robolectric 解决依赖问题,使测试运行在 JVM 上,大大提高测试运行效...

2321
来自专栏向治洪

小程序实现原理解析

概述 作为一名前端开发,如果你还停留在应用开发层面,那你就OUT了,快来跟我一起探讨下小程序框架本身底层实现的一些技术细节吧,让我们从小程序的运行机制来深度了解...

9979
来自专栏贺嘉的专栏

如何用Baas快速在腾讯云上开发小程序之系列4:实现客户侧商品列表、商品详情页程序

本文将分享如何在腾讯云上实现小程序的商品展示和数据库查询操作。通过实现商品列表、商品详情页程序,熟练掌握云端数据表查询操作,包括掌握小程序调试方法、掌握小程序操...

8520

扫码关注云+社区