引言
首先, 作为一名前端开发, 我工作以来使用的一直是 React
。那么如果我想快速入手(APP
)的开发, React Native
则必然是不二之选。有 React
开发经验, 一切也行会变得简单, 但不管怎么说 Web
开发和移动端开发肯定是有很多不同的, 甚至移动端开发起来可能更为复杂、麻烦的!
那么, 对我而言, 学习 React Native
开发之前, 了解 React
和 React Native
开发之间的差异, 可以帮助我进行针对性的学习。
一、相同点
以下是 React(Web)
和 React Native
的共同点:
- 首先它们都是基于
JavaScript
进行开发的, 或严谨的讲都是基于ECMAScript
(核心语法) 进行开发的。 - 它们都是使用核心
React
库, 所以都可以使用核心的React API
和语法(JSX
)进行开发 - 都是使用虚拟
DOM
来渲染他们的应用程序 - 它们编码思想是一样的, 都使用相同的基于组件的架构进行开发, 这意味着开发人员可以将他们的应用程序分解成更小、更易于管理的部分
- 数据请求, 两者都支持
fetch
, 需要注意的是React Native
并不能直接调用XMLHttpRequest
, 需要react-native-fetch-blob
处理文件下载 - 状态管理, 一些常用的
React
状态管理库都是可以使用的, 但是在React Native
中推荐用Context + Zustand
代替Redux
, 性能更优
补充:
JavaScript
其实包含了三个核心部分:ECMAScript
(核心语法)、DOM
(文档对象模型)、BOM
(浏览器对象模型), 而DOM
(文档对象模型) 和BOM
(浏览器对象模型) 其实是Web
开发独有的, 这里唯一相同的是都使用ECMAScript
(核心语法)进行开发。
二、渲染不同
React | React Native | |
---|---|---|
渲染目标 | 浏览器 DOM |
原生 UI 组件, 编码方式相同, 在构建时通过桥接机制渲染到 iOS/Android 原生视图 |
渲染引擎 | 依赖浏览器 | 依赖 Native 端的 UIKit(iOS) / View(Android) |
示例:
js
// React Web
<div style={{ width: '100px', height: '100px', backgroundColor: 'blue' }} />
// React Native
<View style={{ width: 100, height: 100, backgroundColor: 'blue' }} />
三、组件不同
对于 WEB
开发, HTML
是基础中的基础, 标签可以视为最小化组件。而在 React Native
中则提供一套不同于 Web
的组件(标签
), 而我们则是基于这套组件来绘制页面! 在构建应用时, React Native
则会将 JS
代码构建为对应平台端的应用。
Web (React) | React Native |
---|---|
<div> |
<View> |
<span> 、<p> |
<Text> (所有文本必须用 <Text> 包裹, 否则无法显示) |
<img> |
<Image> |
<button> |
<TouchableOpacity> <Pressable> <Button> |
<input> |
<TextInput> |
window.alert() |
Alert.alert()(iOS) / ToastAndroid.show()(Android) |
四、样式不同
对于 WEB
开发, CSS
肯定是重要的一环, 可控制网页的外观和布局。同样的对应移动端, 绘制界面跑不掉的就是外观和布局了。那么 React Native
中又是如何设置样式的呢?
React (Web) | React Native | |
---|---|---|
样式定义 | CSS / styled-components / inline-style / CSS-in-JS |
仅支持 CSS-in-JS , 可用属性大体上和 CSS 差不多 |
选择器 | 支持 class、id、tag 等丰富的选择器 |
没有所谓的选择器 |
单位 | px、em、rem、% 等丰富的尺寸单位 |
只有一个尺寸单位(无单位), 默认尺寸单位为 dp (设备独立像素) |
伪类 | :hover、:focus 等丰富的伪类、伪元素 |
不支持, 需要使用 state 来实现一些相同效果 |
动画 | 仅通过 CSS 就可以实现各动画 |
只能使用专门的 API 来实现 |
示例:
js
// React Web
<div className="box">Hello</div>
<style>
.box { width: 100px; height: 100px; background: blue; }
</style>
// React Native
<View style={{ width: 100, height: 100, backgroundColor: 'blue' }}>
<Text>Hello</Text>
</View>
五、事件不同
在 WEB
开发中, 事件(Event)
既属于 DOM(文档对象模型)
也属于 BOM(浏览器对象模型)
, 具体取决于事件的类型和作用范围。DOM
事件是发生在 HTML
文档元素上的事件。而 BOM
事件是和浏览器窗口或 navigator
、history
、location
、screen
等 BOM
对象相关的事件。总之, 这些事件是独属于 WEB
页面的, 不适用于 React Native
, 在 React Native
中有自成一套的事件系统。
React (Web) | React Native | |
---|---|---|
事件模型 | 依赖 DOM 、BOM 事件 |
依赖 RN 事件系统 |
事件名(功能相同, 名称不同) | onClick 、onMouseEnter |
onPress 、onLongPress 、onLayout |
触摸事件 | onTouchStart 、onTouchMove |
GestureResponder (手势识别) |
示例:
js
// React Web
<button onClick={() => alert('Clicked!')}>Click Me</button>
// React Native
<TouchableOpacity onPress={() => Alert.alert('Clicked!')}>
<Text>Click Me</Text>
</TouchableOpacity>
六、路由
WEB
页面的载体是浏览器, 不同的页面是通过 URL
来进行识别的, 但是在移动端中, 本质上是不存在 URL
的。而 React Native
实际上是使用自己的一套路由系统。从底层来讲其实就是数据管理(栈式管理)
| | React (Web) | React Native | | --- | --- | | 路由库 | react-router-dom
| react-navigation
| | 页面跳转 | history.push('/home')
| navigation.navigate('Home')
| | URL
结构 | http://example.com/home
| 无 URL
(本质是栈式管理) |
补充: React Native
中的路由系统本质上是栈式管理(Stack Navigation), 它的工作方式类似于浏览器的历史记录, 每次打开一个新页面, 相当于往栈(Stack
)里压入(push
)一个新的页面, 返回时则弹出(pop
)页面, 从而回到上一个页面。
七、本地数据缓存
在 React Native
和 Web(React)
端, 本地数据存储的方式和 API
也有很大区别。
7.1 Web: 常见存储方式
localStorage
: 持久存储
- 容量限制:
5MB
左右 - 作用域: 跨页面可用
- 缺点: 同步
API
, 可能会影响性能
js
localStorage.setItem('key', 'value');
console.log(localStorage.getItem('key')); // 'value'
localStorage.removeItem('key');
sessionStorage
: 临时存储, 页面关闭即丢失
- 作用域: 仅限当前标签页
- 适用场景: 存储临时会话数据,如用户状态
js
sessionStorage.setItem('key', 'value');
console.log(sessionStorage.getItem('key')); // 'value'
sessionStorage.clear();
IndexedDB
: 大数据存储
- 存储结构化数据(对象)
- 容量比
localStorage
更大 - 适用于离线应用
js
const request = indexedDB.open('MyDatabase', 1);
request.onsuccess = () => {
const db = request.result;
const tx = db.transaction('store', 'readwrite');
tx.objectStore('store').put({ id: 1, name: 'Alice' });
};
Cookies
- 主要用于身份验证:
JWT
、Session ID
- 存储大小小于
4KB
- 可能会影响性能(每次请求都会携带)
js
document.cookie = "username=John; expires=Fri, 31 Dec 2025 23:59:59 GMT; path=/";
7.2 React Native: 常见存储方式
AsyncStorage
: 官方推荐, 类似localStorage
, 但是官方已废弃, 推荐MMKV
- 异步存储, 不会阻塞主线程
- 容量不受
5MB
限制 - 适用于小型数据(用户配置、Token 等)
- 缺点就是读取性能一般, 推荐使用
MMKV
替代
js
import AsyncStorage from '@react-native-async-storage/async-storage';
await AsyncStorage.setItem('key', 'value');
const value = await AsyncStorage.getItem('key');
console.log(value); // 'value'
await AsyncStorage.removeItem('key');
MMKV
: 高性能替代AsyncStorage
- 超快(C++ 实现, 比
AsyncStorage
快30~50
倍) - 支持数据类型: String、Boolean、Number、Object
- 适用于高频数据访问, 如用户状态、缓存等
js
import MMKVStorage from 'react-native-mmkv';
const storage = new MMKVStorage.Loader().initialize();
storage.setString('key', 'value');
console.log(storage.getString('key')); // 'value'
react-native-sqlite-storage
: 数据库存储
- 适用于存储结构化数据, 如聊天记录、用户信息
- 性能较好, 比
AsyncStorage
适用于大数据存储 - 适用于离线应用
js
import SQLite from 'react-native-sqlite-storage';
const db = SQLite.openDatabase({ name: 'test.db' });
db.transaction(tx => {
tx.executeSql('CREATE TABLE IF NOT EXISTS Users (id INTEGER PRIMARY KEY, name TEXT)');
tx.executeSql('INSERT INTO Users (name) VALUES (?)', ['Alice']);
});
react-native-fs
: 文件存储
- 适用于存储: 图片、音频、
PDF
- 适合于离线缓存
js
import RNFS from 'react-native-fs';
const path = RNFS.DocumentDirectoryPath + '/test.txt';
await RNFS.writeFile(path, 'Hello, world!', 'utf8');
const content = await RNFS.readFile(path, 'utf8');
console.log(content); // Hello, world!
7.3 存储方式推荐
存储需求 | Web(React) | React Native |
---|---|---|
小数据 (用户 Token ) |
localStorage / sessionStorage |
MMKV (推荐) / AsyncStorage |
大数据(聊天记录) | IndexedDB |
react-native-sqlite-storage |
身份认证 | Cookies + HTTPOnly |
react-native-cookies |
图片 / 视频缓存 | Cache API |
react-native-fs |
离线应用 | IndexedDB + Service Worker |
SQLite / MMKV |
八、动画
Web(React)
和 React Native
在动画实现方式、性能优化 和 API
方面有很大的不同。
Web(React) | React Native | |
---|---|---|
CSS 动画 |
transition / @keyframes |
不支持, 只能通过 JS 来实现动画 |
JS 控制动画 |
requestAnimationFrame |
Animated API(官方推荐) / react-native-reanimated |
第三方库 | Framer Motion / GSAP |
react-native-reanimated(更高级 & 性能更高) |
硬件加速 | 依赖 GPU 渲染 (如 will-change ) |
依赖 useNativeDriver |
复杂交互 | Web 交互较多 (鼠标、滚动等) |
依赖 react-native-gesture-handler |
在性能优化上来讲, React Native
动画比 Web
更难优化, 要尽量用 useNativeDriver
或 react-native-reanimated
让动画在原生线程执行, 而不是 JS
线程。