React-Native 是什么
React Native产出的并不是“网页应用”, 也不是“HTML5应用”,也不是“混合应用”。 它的最终产品是一个真正的移动应用,从使用感受上和用Objective-C或Java编写的应用相比几乎是无法区分的。 React Native所使用的基础UI组件和原生应用完全一致。 你要做的就是把这些基础组件使用JavaScript和React的方式组合起来。
React-Native 特点
-
1.性能:
很多人说 RN 的性能比不上原生的 App,这个说法是要看具体的场景。 在一般的应用场景下 RN 的表现和原生 App 是没有太大的差别的,一个 App 也不会到处都是复杂的交互效果。一些简单的点缀动画再加上列表图片等才是一个 App 最常见的内容,这种情况下它们之间的表现是一样的。 RN 本身只是使用 JS 处理了 UI 渲染之前的一些逻辑,在最终的渲染上其实使用的还是原生的逻辑,尤其是渲染完成之后更是和原生的没有半点区别。
Swift原生应用与React-Native应用性能对比
https://juejin.im/post/58ca6d5f44d90400682a215c -
2.开发效率:
React-Native开发的UI做到一份代码能在两个平台运行,通常要适配部分代码只有总代码的5%。 -
3.组件化开发:
React推荐以组件的方式去重新思考UI构成,将UI上每一个功能相对独立的模块定义成组件,然后将小的组件通过组合或者嵌套的方式构成大的组件,最终完成整体UI的构建。
这样开发出来的代码结构清晰,公用性高、可移植性高,上一个项目的某些组件,可以很方便的拿来用在下一个项目中使用。 -
4.灵活高效的热更新:
用户不论是使用Android手机还是iPhone手机下载了应用,开发者都可以在用户无感知的情况下加入新页面,新功能与新的业务逻辑
一、架构理念
“Learn once, write anywhere” ,代表着 Facebook对 react native 的定义:学习 react ,同时掌握 web 与 app 两种开发技能。 react native 用了 react 的设计模式,但UI渲染、动画效果、网络请求等均由原生端实现。开发者编写的js代码,通过 react native 的中间层转化为原生控件和操作,比ionic等跨平台应用,大大提高了的用户体验。
总结起来其实就是利用 JS 来调用 Native 端的组件,从而实现相应的功能。
如下图所示,react native 的跨平台是实现主要由三层构成,其中 C++ 实现的动态连结库(.so),作为中间适配层桥接,实现了js端与原生端的双向通信交互。这里最主要是封装了 JavaScriptCore 执行js的解析,而 react native 运行在JavaScriptCore中,所以不存在兼容的问题。
其中在IOS上直接使用内置的javascriptcore, 在Android 则使用webkit.org官方开源的jsc.so
react native 跨平台二、实现原理
和前端开发不同,react native 所有的标签都不是真实控件,JS代码中所写控件的作用,类似 Map 中的 key 值。JS端通过这个 key 组合的 Dom ,最后Native端会解析这个 Dom ,得到对应的Native控件渲染,如 Android 中<view> 标签对应 ViewGroup 控件。
image.png在 react native 中,JS端是运行在独立的线程中(称为JS Thread )。JS Thread 作为单线程逻辑,不可能处理耗时的操作。那么如 fetch 、图片加载 、 数据持久化 等操作,在 Android 中实际对应的是 okhttp 、Fresco 、SharedPreferences等。而跨线程通信,也意味着 Js Thread 和原生之间交互与通讯是异步的。
可以看出,跨平台的关键在于C++层,开发人员大部分时候,只专注于JS 端的代码实现。 在原生端提供的各种 Native Module 模块(如网络请求,ViewGroup控件),和 JS 端提供的各种 JS Module(如JS EventEmiter模块),都会在C++实现的so中保存起来,双方的通讯通过C++中的保存的映射,最终实现两端的交互。通信的数据和指令,
React Native 框架内部已提供了很多的内置组件。如 View、Text 等基本组件,用于一些功能布局的 Button、Picker 等,用于列表展示的各种 List 组件和对应 iOS 平台与 Android 平台的特定组件、API 等。
组件三、预备知识
有些前端经验的小伙伴学起 React Native 就像老马识途,东西都差不多,变来变去也玩不出什么花样。
ES6、ES7、ES8:是JavaScript语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言(class、箭头函数、解构...)
CSS:React Native 的 FlexBox 用来为组件布局的,和 CSS 亲兄弟关系。
JavaScript:用 JavaScript 写,能不了解一下吗? JavaScript 之于 React Native 就如同砖瓦之于摩天大楼。
React JSX:React 使用 JSX 来替代常规的 JavaScript。JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。
React-Navigation:在 web 浏览器中, 你可以使用 () 标签作为锚点,在iOS原生应用中使用UINavigationController 跳转页面,在RN中则是React-Navigation
Mobx:全局的状态管理,移动端开发中最常见的场景就是,很多页面会公用登录人信息,如果按照常规的移动端开发方式,就是什么时候用,什么时候从内存中取,其实这是有性能消耗的。使用了mobx之后,只需要在登录的时候,或者一次用户信息,通过依赖注入,就可以到处使用了
开始学习 React Native
React Native 社区相对比较成熟,中文站的内容也比较全面,从入门到进阶,环境安装到使用指南,学习 React Native 推荐从官网 reactnative.cn开始。FlexBox 布局、组件、API 建议在该官网查看,注意网页顶部可以切换 React Native 的历史版本。
1.1 安装开发环境
-
React Native 官网推荐搭建开发环境指南传送门。(记得设置
App Transport Security Settings
,允许 http 请求) - 已建立原生项目,将 React Native 集成到现有原生项目传送门
- 基于第2点,React Native 与原生混编的情况下,React Native 与原生如何通信传送门
- 在 IDE 选择这一点上,不要过多纠结,个人使用 WebStorm,比较省心。
1.2 生命周期
React Native 提供了多个生命周期函数,供开发者作为切入组件生命周期的钩子(hook),这样在对应的时间点程序就可以做对应的逻辑处理,从而实现相应的功能。
image.png
class Clock extends React.Component {
// 构造函数 通常进行一些初始化操作 如定义 state 初始值
constructor(props) {
super(props);
}
// 组件已挂载
componentDidMount() {}
// 组件即将被卸载
componentWillUnmount() {}
// 渲染函数
render() {
return (
<View></View>
);
}
}
1.3 组件间通信
React Native 开发最基本的元素就是组件,React Native 与 React 一样,也会涉及到组件之间的通信,用于数据在组件之间的传递
Props 与 State
一个组件所有的数据来自于 Props 与 State ,分布是外部传入的属性和内部状态。
Props 是父组件给子组件传递数据用的,Props 由外部传入后无法改变,可以同时传递多个属性。
// 父组件 传递一个属性 name 给子组件
<Greeting name='xietao3' />
// 子组件使用父组件传递下来的属性 name
<Text>Hello {this.props.name}!</Text>
State :用来控制组件内部状态,每次修改都会重新渲染组件。
// 初始化 state
constructor(props) {
super(props);
this.state = { showText: 'hello xietao3' };
}
// 使用 state
render() {
// 根据当前showText的值决定显示内容
return (
<Text>{this.state.showText}</Text>
);
}
// 修改state,触发 render 函数,重新渲染页面
this.setState({showText: 'hello world'});
举个栗子(如果理解了就跳过吧):
我们使用两种数据来控制一个组件:props 和 state。 props 是在父组件中指定,而且一经指定,在被指定的组件的生命周期中则不再改变。 对于需要改变的数据,我们需要使用 state 。
一般来说,你需要在 constructor 中初始化 state ,然后在需要修改时调用setState方法。
假如我们需要制作一段不停闪烁的文字。文字内容本身在组件创建时就已经指定好了,所以文字内容应该是一个 prop 。而文字的显示或隐藏的状态(快速的显隐切换就产生了闪烁的效果)则是随着时间变化的,因此这一状态应该写到 state 中。
1.4 组件与 API
说到组件就不得不说 React Native 的组件化思想,尼古拉斯 · 赵四 曾经说过,组合由于继承。简单来说就是多级封装嵌套、组合使用,提高基础组件复用率。
组件怎么用?
授人以鱼不如授人以渔,点击这里打开官方文档,在左边导航栏中找到你想使用的组件并且点击,里面就有组件的使用方式和属性的详细介绍。
1.5 关于 API
建议写第一个 Demo 之前把所有 API 浏览一遍,磨刀不误砍柴工,不一定要会用,但一定要知道这些提供了哪些功能,后面开发中可能会用得上。API 列表同样可以在官网左边导航栏中找到。
2、助力 React Native 起飞
- CodePush
React Native 热更新的发动机,接入的时候绕了很多圈圈,后面发现接入还挺方便的。CodePush 除了可以使用微软提供的服务进行热更新之外,还可以自建服务器进行热更新。
推荐教程:
4、与原生端通信
填坑:
- 原生端的 Manager 文件如果有 RCT 前缀,在 RN 中引用的时候不要加 RCT。
- 原生 UI 组件的 RCTBubblingEventBlock 类型属性命名一定要以 on 开头,例如 onChange。
3.2 在 React Native 中发消息通知给原生端(由于RN调用原生端是异步的,最好在回调中通过通知把消息传递到具体的类)
3.3 在原生端发消息通知给 React Native (建议在Manager中写一个类方法,这样外部也可以灵活发送通知)
四.大厂React-Native 实践
- 京东: [JDReact]
https://www.infoq.cn/article/jd-618-ReactNative-jingdong-practise - 去哪: [Qunar]
http://ued.qunar.com/qrn/ - [携程技术中心React Native Meetup活动经验分享]https://blog.csdn.net/liu__520/article/details/52903667
最终分析
随着React Native的不断壮大,可以毫无保留的说React Native是现在和未来很长一段时间移动开发人员的必备技能。React Native这种模式学习成本较高,所以需要前期投入不少时间才能达到较好水平,但是有了一定水准后,开发起来它的优势就体现出来了,性能不逊色原生,而且开发速度也很快。
同时我们可以关注的是链接-使用React Native的各大app,百度,腾讯,京东包括国外的FaceBook,Instgram等优秀的app都在使用React Native。
网友评论