混合型移动应用(Hybrid apps)可以借助多种 web 技术搭建应用,并将其打包为原生应用(Native apps)以适应于多种移动平台。
注意:React Native 在2015年首发。然而,在本项目开始时,React Native Android 版还未发布,因此我们无法使用之。
混合型应用中的挑战
混合式移动应用已经不是什么新鲜事了。同时,它当然也不是编写所有应用的万能钥匙。真正的挑战在于,达到原始应用的极致体验,兼具流畅的动画效果与时尚的用户界面。
大多数混合式应用项目一开始,都具备快速、响应及时的用户界面。之后,却很容易撞上南墙。这通常出现在项目后期,此时,经过数周的努力,项目已经添加了许多的功能,DOM 中的内容也愈加丰富。
此时,视图组件间的关系变得非常难以追踪,而事件监听器的循环依赖会导致过多的 DOM 读写操作。
进入 React
React 知道根据组件的状态进行重新渲染,并且保存一个虚拟 DOM 以实现高效的重新渲染。这种方法非常棒,因为我们写代码时就好像在重新渲染整个模板,而实际上 React 只会更新发生过改动的 DOM。
JSX
React 与常见框架的最大差别在于,JavaScript 逻辑与 Markup(标记)模板使用 JSX 语法写在同一个文件中。
class MyTitle extends Component {
render() { return (
<header>
<h1>Hello World</h1>
</header>
)
}
}
适应这种变化需要一点时间。但是一旦掌握,就能极大地你的提高生产力。
Mixins 对决 Composition
/**
* Exports a higher order component wrapping the component to decorate
* @param ComponentToDecorate the component which will be decorated
*/
export const withDecoratedData = ComponentToDecorate =>
class extends Component {
constructor() {
this.state = { data: null };
}
componentDidMount() {
this.setState({ data: 'Decorated hello!' });
}
render() {
return <ComponentToDecorate {...this.props} data={this.state.data} />;
}
}
之后,可以使用 ES2016 装饰器(Decorator)来应用组件。我们可以在 Babel 中选择启用 ES2016 装饰器。
import {withDecoratedData} from '...';
// Decorate component using ES7 decorator '@'
@withDecoratedData
class MyComponent extends Component {
render() {
return <div>{this.data}</div>;
}
}
通过这种方式,我们将视图组件(View components)与我们的数据存储(Data stores)进行了联结。
单向数据流
对于一个应用而言,视图层只是表面——表面背后的部分才是错综复杂的境地。React 可以与大多数其他框架结合使用,实现对现有数据模型的渲染。然而,大规模 MVC 应用与循环依赖的问题仍旧存在,因此,Facebook 推出了具备“单向数据流”的 Flux 设计模型,以使数据流动更容易预见。
为什么选用 React 创建混合型移动应用?从 iOS 8 开始,我们终于可以在惯性滚动阶段(也即在触摸停止后持续的滚动动作)设置滚动事件。旧版 UIWebView 并不支持该功能,而 Cordova 默认使用旧版 UIWebView。
总结
对于使用 React 完成此项目,我们对自己的选择感到欣慰。但是,我们仍有一些值得注意的地方,以便在下次做出调整。
优势
- 渲染性能的提升 —— React 能高效地实现 DOM 的更新
- 简化可重用组件的编写
- 强大的 JSX 语法,实现数据与标记模板的结合
- 一旦体系决策达成,组件开始重用,生产力就能提高
- 避免开发者直接接触 DOM (也即:减少伤害性能的风险)
缺点
- 如果不人为直接修改 DOM,使用 React State 很难实现时间线复杂的动画
- 并非全面的解决方案 ——缺少经验的开发者很难入门。需要选择一个 Router, Flux 库或数据层等等
- 新的 React 版本发布较为频繁,生态系统不够成熟 ——大多数插件的变化比 React 还频繁,而且 API
一直在变化。在本项目中,我们在react-router
与Alt
中都遇到过断层式的 API 变化。Alt
的变化尤其迅速,相关文档也不是最新的。在下一个 React 项目中,我们会专注于 。