本文作者:IMWeb helondeng 原文出处:IMWeb社区 未经同意,禁止转载
React-Native 基于目前React来开发IOS原生应用,Android版本将在年底推出。
为什么需要React-Native
目前主流的应用大体分成三类:Native App, Web App, Hybrid App.
Native App
优点
- 性能好,性能好,还是性能好 缺点
- 开发成本高,无法跨平台
- 升级困难
Web App
优点
- 跨平台,Write Once , Run Anywhere
- 版本升级容易 缺点
- 无法系统系统级的API
- 临时入口,用户留存度低
- 性能差
Hybrid App
Native App 和 Web App 折中的方案,保留了 Native App 和 Web App 的优点。但是最受吐槽的还是性能差。页面渲染效率低,在Webview中绘制界面,实现动画,资源消耗都比较大。
React-Native
What we really want is the user experience of the native mobile platforms, combined with the developer experience we have when building with React on the web.
这是 React-Native 设计的初衷: 既保留流畅的用户体验,有保留React的开发效率。
React-Native 做了什么
- React-Native 丢弃了 Webview。
- 复用React,将 Dom 结构de改变通过 diff 算法处理后,由 js 传递给 native 进行底层视图布局。
- css-layout引擎,前端可以继续写熟悉的 css 语法,由引擎转化成 oc 底层的布局。
- 对 js 暴露底层常用的 UI 组建。js 层可以直接对这些组件进行布局。
对应前端的开发模式的变化:
- JSX vs Html
- css-layout vs css
- ECMAScript 6 vs ECMAScript 5
- React-Native vs DOM
如何开始
1) 安装以来的包和软件,参考这里。 2) 运行下面的命令,初始化项目:
代码语言:javascript复制react-native init helloworld
3) 在项目目录下面,运行:
代码语言:javascript复制 npm install
npm start
4) 使用 Xcode 开发项目,运行,即可看到模拟器中的效果。这里有可能会运行失败报错,主要可以从2方面排查:
- AppDelegate.m 中
jsCodeLocation
的定义是否正确。 - 删除 /Users/{you}/Library/Developer/Xcode/DerivedData 文件夹,重启Xcode。 (PS: 官方给的例子好几个都有上面的问题,跑不起来)
5) 修改目录下的 index.ios.js 文件,定制自己的UI。
代码语言:javascript复制 render : function() {
return (
<View style={styles.container}>
<Text>Hello World!</Text>
</View>
)
}
cmd R 刷新模拟器即可看到效果,就是这么简单。
进阶玩法,自定义UI组件
如下图,实现课程列表的效果(下图是react-native实现效果,原效果猛戳这里,只实现了页面中的listview):
代码语言:javascript复制 var CList = React.createClass({
getInitialState: function(){
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
return {
dataSource: ds.cloneWithRows(data),
load: false
}
},
render: function(){
return (
<ListView dataSource={this.state.dataSource}
renderRow={this.renderRow}
style={styles.courseList} />
)
},
renderRow: function(course){
course._price = course.price == 0 ? '免费' : '¥' (course.price / 100).toFixed(2);
course._priceCla = {};
course._priceCla.color = course.price == 0 ? '#5db61b' : '#e85308';
return(
<TouchableOpacity>
<View style={styles.row}>
<View style={styles.container}>
<Image style={styles.face} source={{uri : course.cover_url '222'}}/>
<View style={styles.right}>
<Text style={styles.name} numberOfLines="2">{course.name}</Text>
<Text style={styles.agency}>{course.agency_name}</Text>
<View style={{flex: 1, flexDirection: 'row'}}>
<Text style={[styles.price,course._priceCla]}>
{course._price}
</Text>
<Text style={{color: 'gray', flex: 1}}>{course.see_num}人观看</Text>
</View>
</View>
</View>
</View>
</TouchableOpacity>
)
}
});
module.exports = CList;
在入口文件中,require上面的文件,然后在render方法中直接调用改组件即可。
代码语言:javascript复制 render: function() {
return (
<NavigatorIOS
style={styles.container}
initialRoute={{
title: '课程列表',
component: CList,
}} />
);
}
总结
小试了一下 React-Native,还是很强大的,期待Android的版本。文章中若有不对,欢迎斧正、交流。