- Published on
React Native
- Authors

- Name
- MissTree
React Native 前期准备
React Native 官方文档 React Native 中文网
环境搭建
- 安装 Node.js
- 安装 JDK
- 安装 Android Studio 和 Android SDK
- 安装 Xcode 和 CocoaPods -- IOS环境
- Xcode 是 Apple 开发的集成开发环境,用于开发 iOS 应用。
- CocoaPods 是一个用于管理 iOS 项目依赖的第三方库,React Native 项目需要使用 CocoaPods 来管理依赖。
- 配置环境变量
- Hyper-V 相关设置
在window系统下只能开发 android,mac 系统可以同时开发 ios 和 android
expo cli
expo 是一个用于开发 React Native 应用的工具,它提供了一套命令行工具和一套开发环境,可以让开发者更方便地开发 React Native 应用。
# 全局安装脚手架
npm install -g expo-cli
# 创建项目
expo init MyApp
cd MyApp
# 启动项目 yarn start
expo start
# 直接创建项目
npx create-expo-app@latest
项目运行在 http://localhost:8081/ exp://192.168.142.252:8081
› Using Expo Go
› Press s │ switch to development build
› Press a │ open Android
› Press w │ open web # 打开浏览器
› Press j │ open debugger
› Press r │ reload app
› Press m │ toggle menu
› shift+m │ more tools
› Press o │ open project code in your editor # 打开编辑器
› Press ? │ show all commands

react-native cli
react-native cli 是 React Native 官方提供的命令行工具,它提供了一套命令行工具和一套开发环境,可以让开发者更方便地开发 React Native 应用。
# 全局安装脚手架
npm install -g react-native-cli
# 创建项目
npx react-native init MyApp
cd MyApp
# 启动项目
npx react-native run-ios
npx react-native run-android
# 启动模拟器后时间可能有点长,需要等待
# 创建项目目录 src/compnonents src/routes src/screens src/utils
# 添加项目依赖
yarn add react-native-elements react-native-vector-icons react-native-safe-area-context
新版本替代 使用 @react-native-community/cli 代替了旧的 react-native-cli
npm install -g @react-native-community/cli
npx react-native init MyApp
SafeAreaView
react-native-safe-area-context是处理安全区域的库。提供SafeAreaView,虽然这个组件在rn中也有,但是rn中的只⽀持 ios10+,不⽀持ios和android的⽼版本。项⽬中建议选择react-native-safe-area-contex的SafeAreaView。
其他常用工具
- scrcpy 安卓投屏工具
示例代码
import React, {useState} from 'react';
import { View, Text, StyleSheet, SafeAreaView, Image,
ImageBackground, TextInput, ScrollView,} from 'react-native';
import {Button} from 'react-native-elements';
const logo = 'https://zh-hans.reactjs.org/logo-og.png';
export default function App() {
const [count, setCount] = useState(0);
const [text, setText] = useState('default');
return (
<SafeAreaView>
<ScrollView>
<Text>App</Text>
<Image source={{uri: logo}} style={styles.logo}/>
<ImageBackground source={{uri: logo}} style={styles.logo}>
<Text style={{color: 'white'}}>Inside</Text>
</ImageBackground>
<Button title={count + ''}
onPress={() => setCount(count + 1)}
buttonStyle={styles.btn}/>
<TextInput value={text}
onChangeText={txt => setText(txt)}
style={styles.txt}/>
<Text style={[styles.txt, {borderColor:'green'}]}>
<Text style={styles.bold}>⽂本: </Text>
<Text>{text}</Text>
</Text>
<View style={[styles.txt, {borderColor:'green'}]}>
<Text style={styles.bold}>⽂本: </Text>
<Text>{text}</Text>
</View>
{/* //! 溢出 */}
<Text>omg:</Text>
<Text numberOfLines={1}>{'书名'.repeat(100)}</Text>
{/* <Text>{'书名'.repeat(1000)}</Text> */}
</ScrollView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
logo: {
width: 100,
height: 100,
},
btn: {
width: 100,
height: 100,
backgroundColor: 'red',
},
txt: {
width: 100,
height: 100,
backgroundColor: 'yellow',
},
bold: {
fontWeight: 'bold',
},
});
与其他框架的对比


React Native UI
| React Native UI 组件 | Android 视图 | iOS 视图 | web | 描述 |
|---|---|---|---|---|
| <View> | <ViewGroup> | <UIView> | <div> | 支持使用弹性框、样式、一些触摸处理和可访问性控件进行布局的容器 |
| <Text> | <TextView> | <UITextView> | <p> | 显示、设置样式、嵌套文本字符串,甚至处理触摸事件 |
| <Image> | <ImageView> | <UIImageView> | <img> | 显示不同类型的图像 |
| <ScrollView> | <ScrollView> | <UIScrollView> | <div> | 可包含多个组件和视图的通用滚动容器 |
| <TextInput> | <EditText> | <UITextField> | <input type="text"> | 允许用户输入文本 |
样式
在react native中,样式是通过StyleSheet.create()方法来创建的,这个方法接受一个对象,对象的属性名是样式名,属性值是样式值。 样式属性示例
import Dimensions from 'react-native-dimensions';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
width: Dimensions.get('window').width/4, // 获取屏幕宽度设置几分之一
height:100
},
text: {
fontSize: 20,
color: '#000',
},
});
样式没有继承性,Text 的样式可以继承,尺寸大小没有单位
常用组件
- TouchableOpacity: 创建一个可点击的组件
- TouchableHighlight: 创建一个可点击的组件,并且在点击时会有一个高亮效果
- TouchableWithoutFeedback: 创建一个可点击的组件,并且在点击时不会有任何效果
- Modal: 创建一个模态框
- SectionList: 创建一个列表,可以分组显示
- Keyboard
- Animated
- PanResponder
- DrawerLayoutAndroid
- DrawerLayout
- ViewPagerAndroid
- ViewPager
- WebView
- Picker
- Alert: 显示一个警告对话框
- StatusBar: 状态栏组件
- Button: 创建一个按钮
- ActivityIndicator: 加载指示器
- DatePickerAndroid: 显示一个日期选择器
- DrawerLayoutAndroid: 创建一个抽屉布局
- FlatList: 高性能列表组件
- Image: 显示一个图片
- KeyboardAvoidingView: 避免键盘遮挡
- Modal: 创建一个模态框
- Picker: 创建一个选择器
导航跳转
React Native并没有浏览器那样的历史栈,所以React Navigation就来做这件事了。
yarn add @react-navigation/native react-native-screens react-native-safe-area-context
React Navigation 提供了三种类型的导航器:
- Stack Navigator:栈导航器,用于管理页面之间的跳转,类似于浏览器的历史栈。
- yarn add @react-navigation/native-stack
- Tab Navigator:标签导航器,用于在多个页面之间进行切换,类似于浏览器的标签页。
- Drawer Navigator:抽屉导航器,用于在多个页面之间进行切换,类似于浏览器的侧边栏。
Stack Navigator
createNativeStackNavigator是⼀个函数,返回⼀个对象,这个对象⾥有两个都是React组件的属性:Screen and Navigator。注意它们的包裹关系:NavigationContainer->Navigator->Screen Screen属性:
- name:路由名称,⽤于标识路由,必须唯⼀
- component:该路由对应的组件
- options:该路由的配置项,例如标题、头部样式等,也可以通过options的title修改
- initialParams:给组件参数
Navigator属性:
- initialRouteName:初始路由名称,默认为第一个路由
- screenOptions:全局路由配置项,例如标题、头部样式等
// app.js
import React from 'react';
import {NavigationContainer} from '@reactnavigation/native';
import RootRouter from './RootRouter';
export deault function App () {
return (
<NavigationContainer>
<RootRouter />
</NavigationContainer>
);
}
// RootRouter.js
import React from 'react';
import {View, Text} from 'react-native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import HomeScreen from '@/screens/HomeScreen';
import UserScreen from '@/screens/UserScreen';
const {Screen, Navigator} =createNativeStackNavigator();
export default function RootRouter() {
return (
// ! SafeAreaView不能写这⾥
// <SafeAreaView>
<Navigator>
<Screen name="home" component={HomeScreen} />
<Screen name="user"
component={UserScreen}
options={{title: '⽤户中⼼'}}
initialParams={{name: '我是⼩明'}}
/>
</Navigator>
// </SafeAreaView>
);
}
// Link跳转
<Link to={{screen: 'user', params: {id: 'jane'}}}>
Go to Jane's profile
</Link>
navigation
// navigation.navigate('home', {screen: 'home', params: {id: 'jane'}});
// 事件跳转
<Button
title="go home"
onPress={() => {
// navigation.push('home');
// navigation.navigate('home');
}}
/>
⻚⾯是否已经存在,执⾏navigation.navigate导致的结果是不同的。如果⻚⾯已经存在,执⾏navigation.navigate则会回到原先的⻚⾯,并且移除原先⻚⾯在历史栈中的记录。如果⻚⾯不存在,则push⼀个新的记录到历史栈中。 但是如果你执⾏navigation.navigate的时候,给⻚⾯添加了参数,那对与历史栈来说,这个记录对于历史栈就是个新的记录了。
平台特定代码
import {Platform, StyleSheet} from 'react-native';
const styles = StyleSheet.create({
height: Platform.OS === 'ios' ? 200 : 100,
});
import {Platform, StyleSheet} from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
...Platform.select({
ios: {
backgroundColor: 'red',
},
android: {
backgroundColor: 'blue',
},
}),
},
});
const Component = Platform.select({
ios: () => require('ComponentIOS'),
android: () => require('ComponentAndroid'),
})();
<Component />;
import {Platform} from 'react-native';
if (Platform.Version === 25) {
console.log('Running on Nougat!');
}
# 不同平台组件
BigButton.ios.js
BigButton.android.js
import BigButton from './BigButton';
注意事项
- Hooks API 是 React Native 0.59 提供的新特性
- 因为 JSX 语法糖的实质是调⽤React.createElement⽅法,所以你必须在⽂件头部引⽤import React from 'react'。