[TOC]
初识 React Native
1.1 React Native的优点
- React Native 则将你的代码解析成真正原生的 UI 组件,利用了所用平台上现有的视图渲染方式
- React 不在 UI 主线程中运行,你的应用可以在不牺牲灵活性的前提下保持高性能
- React Native 的生命周期与 React 相同,当属性(props)或状态(state)发生改变时,React Native 会重新渲染视图
- 与浏览器上的 React 最大的不同在于,React Native 使用了宿主平台上的 UI 元素来代替 HTML 和 CSS
- 对于开发者体验,查看修改结果时不需要重新编译,可以在Chrome 或者 Safari 的开发工具上调试
- 代码复用与知识共享,React Native 不能做到100%跨平台,每个平台都有自己一些特性
1.2 风险和缺点
- 由于 React Native 在项目中会引入额外的一层,因此带来了一些调试上的麻烦,尤其是在 React 和宿主平台进行交互时
React Native 工作原理
2.1 Virtual DOM(虚拟 DOM)与 React 桥接
Virtual DOM 诞生原因
- 在 React 中,Virtual DOM 就像是一个中间层,介于开发者描述的视图与实际在页面上渲染的视图之间
- 为了在浏览器上渲染出可交互的用户界面,开发者必须操作浏览器的文档对象模型(DOM,document object model)
- 这个操作代价昂贵,对 DOM 的过度操作将会给性能带来严重的影响。React 维护了一个内存版本的 DOM,通过计算得出必要的最小操作并重新渲染
Virtual DOM 好处
- Virtual DOM 确实能提升性能,但它主要的潜力在于提供了强大的抽象能力
- 在开发者的代码与实际的渲染之间加入一个抽象层,这带来了很多可能性
React 桥接
image.png- React 可以渲染到多平台上
- 桥接令这一切成为可能,它使得 React 可调用宿主平台开放的 UI 组件
- React Native 目前同时支持了 iOS 和 Android 两种平台。由于 Virtual DOM 提供了抽象层,React Native 也可以支持其他平台,只需为其提供桥接即可
2.2 渲染周期
当 React 在 Web 环境中运行时,渲染周期始于 React 组件挂载之后
image.png接着,React 进入渲染周期并根据需要渲染组件
image.png2.3 在React Native中创建组件
- 所有的 React 代码都存在于 React 组件中。
- React Native 组件与 React 组件大体上一致,但在渲染和样式方面有一些重要的区别。
2.3.1 编写视图
- 当编写 Web 环境的 React 时,视图最终需要渲染成普通的 HTML 元素(<div>、<p>、<span>、<a> 等)
- 而在 React Native 中,所有的元素都将被平台特定的 React 组件所替换
- 最基础的组件是能跨平台的 <View>,这是一个简单且灵活的 UI 元素
- 类似于 <div> 标签
- 在 iOS 中,<View> 组件被渲染成 UIView
- 在 Android 平台上则被渲染成 View
其他组件则是平台特定的。例如,<DatePickerIOS> 组件
下面是从 RNTester 中摘录出来的代码
<DatePickerIOS
date={this.state.date}
mode="time"
/>
image.png
所有的 UI 元素均为 React 组件,而不是像 <div>
这样基础的 HTML 元素,因此我们在使用每一个组件之前,都需要显式地进行导入。例如,我们可以这样导入 <DatePickerIOS>
组件:
import { DatePickerIOS } from "react-native";
平台特定的元素和 API 在官方文档中有特殊的标签,通常使用平台名称作为后缀,例如
<TabBarIOS>
和<ToolbarAndroid>
- 如果你想复用代码,那么这些组件的抽象分离就至关重要
- 如果一个组件封装的是关联逻辑,那就可以被复用
- 如果你乐意的话,还可以为组件设计平台特定的版本,
2.3.2 使用JSX
- 与 React 相一致,React Native 也是通过编写 JSX 来设计视图
- 并将视图标记和控制逻辑组合在一起成为一个文件
- JSX 认为减少心智负担比文件分离更有用
纯 JavaScript 编写 React 组件
class HelloMessage extends React.Component {
render() {
return React.createElement(
"div",
null,
"Hello ",
this.props.name
);
}
}
ReactDOM.render(
React.createElement(HelloMessage, { name: "Bonnie" }), mountNode);
使用 JSX 使其更为简洁
class HelloMessage extends Component {
render() {
// 返回标记,而不是调用createElement方法
return <div>Hello {this.props.name}</div>;
}
}
// 我们不再需要调用createElement方法
ReactDOM.render(<HelloMessage name="Bonnie" />, mountNode);
以上两段代码最终都会在页面上被渲染为下面的 HTML:
<div>Hello Bonnie</div>
2.3.3 原生组件的样式
定义一个React样式
// 定义一个样式
const style = {
backgroundColor: 'white',
fontSize: '16px'
};
在React Native中使用它
// 然后使用它
const txt = (
<Text style={style}>
A styled Text
</Text>);
2.4 宿主平台API
- React 与 React Native 最大的不同,就在于宿主平台的 API
- 在 React Native 中,平台特定的 API 在提供优秀原生的用户体验方面发挥了巨大的作用
- 默认情况下,iOS 和 Android 版本的 React Native 支持许多常用的特性,甚至可以支持任何异步的本地 API
- React Native 的桥接不可能暴露宿主平台全部的 API,如果你需要使用一个未支持的特性,完全可以自己动手添加到 React Native 中
- 隔离和封装这些组件将会给你的应用带来更大的灵活性。当然,这对你开发 Web 应用同样奏效,如果你想共享 React 和 React Native 的代码,请记住像 DOM 这样的 API 在 React Native 中并不存在。
网友评论