1652 lines
43 KiB
Markdown
1652 lines
43 KiB
Markdown
React Native 备忘清单
|
||
===
|
||
|
||
[](https://npmjs.org/package/react-native)
|
||
[](https://www.npmjs.com/package/react-native)
|
||
[](https://github.com/facebook/react-native/network/dependents)
|
||
[](https://github.com/facebook/react-native)
|
||
|
||
适合初学者的综合 [React Native](https://reactnative.dev/) 备忘清单,在开始 [React Native](https://reactnative.dev/) 之前需要先掌握 [react](./react.md) 库
|
||
<!--rehype:style=padding-top: 12px;-->
|
||
|
||
入门
|
||
---
|
||
|
||
### macOS 安装 iOS 环境
|
||
|
||
您将需要 Node、Watchman、React Native 命令行界面、Ruby 版本管理器、Xcode 和 [CocoaPods](./cocoapods.md)
|
||
|
||
```bash
|
||
$ brew install node # Node 14 或更新版本
|
||
$ brew install watchman
|
||
```
|
||
|
||
使用 `.ruby-version` 文件来确保您的 Ruby 版本与所需的一致
|
||
|
||
```bash
|
||
$ ruby --version
|
||
# ruby 2.7.5
|
||
```
|
||
|
||
<red>注意:</red> macOS 12.5.1 附带了 Ruby <pur>**2.6.8**</pur>,这不是 React Native 所要求的,React Native 70+ 需要 Ruby <yel>**2.7.5**</yel>,可以使用下面工具切换版本:
|
||
|
||
- [rbenv](https://github.com/rbenv/rbenv) _推荐_
|
||
- [RVM](https://rvm.io/) _推荐_
|
||
- [chruby](https://github.com/postmodern/chruby)
|
||
- 带有 [asdf-ruby](https://github.com/asdf-vm/asdf-ruby) 插件的 [asdf-vm](https://github.com/asdf-vm)
|
||
<!--rehype:className=cols-2-->
|
||
|
||
创建一个新的应用程序
|
||
|
||
```bash
|
||
$ npx react-native init MyApp
|
||
# 指定 React Native 版本创建
|
||
$ npx react-native init MyApp \
|
||
--version X.XX.X
|
||
# 创建 typescript 版本项目
|
||
$ npx react-native init MyTSApp \
|
||
--template react-native-template-typescript
|
||
```
|
||
|
||
安装依赖
|
||
|
||
```bash
|
||
$ yarn install # 根目录运行
|
||
$ cd ios # 进入 ios 目录
|
||
$ bundle install # 安装 Bundler
|
||
$ bundle exec pod install # 以安装 iOS 依赖项
|
||
```
|
||
|
||
运行你的 React Native 应用程序
|
||
|
||
```bash
|
||
# 启动监听打包 JS 服务,默认端口 8081
|
||
$ npx react-native start
|
||
# 指定 8088 端口
|
||
$ npx react-native start --port=8088
|
||
# 启动 iOS 模拟器运行你的应用
|
||
$ npx react-native run-ios
|
||
```
|
||
|
||
---
|
||
|
||
:- | --
|
||
:- | --
|
||
`⇧` + `⌘` + `2` | 设备窗格
|
||
`⌘` + `R` | 构建并运行
|
||
`摇动您的设备` | 打开<yel>开发者</yel>菜单
|
||
<!--rehype:className=shortcuts-->
|
||
|
||
### macOS 安装 Android 环境
|
||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||
|
||
您将需要 Node、Watchman、React Native 命令行界面、JDK 和 Android Studio
|
||
|
||
```bash
|
||
$ brew install node # Node 14 或更新版本
|
||
$ brew install watchman
|
||
```
|
||
|
||
我们建议使用 [Homebrew](./homebrew.md) 安装名为 Azul Zulu 的 OpenJDK 发行版,发行版为 **Intel** 和 **M1 Mac** 提供 JDK
|
||
|
||
```bash
|
||
$ brew tap homebrew/cask-versions
|
||
$ brew install --cask zulu11
|
||
```
|
||
|
||
下载安装 [Android Studio](https://developer.android.com/studio/index.html)
|
||
|
||
- Android SDK
|
||
- Android SDK Platform
|
||
- Android Virtual Device
|
||
<!--rehype:className=cols-3-->
|
||
|
||
安装安卓SDK,React Native 应用需要 Android 12 (S) SDK,通过 Android Studio 中的 SDK 管理器安装其他 Android SDK
|
||
|
||
> SDK 管理器也可以在 Android Studio “**Preferences**” 对话框中找到,位于 **Appearance & Behavior** → **System Settings** → **Android SDK**
|
||
|
||
- `Android SDK Platform 31`
|
||
- `Intel x86 Atom_64 System Image` 或 `Google APIs Intel x86 Atom System Image` 或 (for Apple M1 Silicon) `Google APIs ARM 64 v8a System Image`
|
||
|
||
接下来,选择 `SDK Tools` 选项卡并选中 `Show Package Details` 旁边的复选框。 查找并展开 `Android SDK Build-Tools` 条目,然后确保选择了 <pur>**31.0.0**</pur>。最后点击 `Apply` 下载并安装 `Android SDK` 及相关构建工具
|
||
|
||
配置 ANDROID_SDK_ROOT 环境变量
|
||
|
||
将以下行添加到您的 `$HOME/.bash_profile` 或 `$HOME/.bashrc`(如果您使用的是 zsh,则为 `~/.zprofile` 或 `~/.zshrc`)配置文件:
|
||
|
||
```bash
|
||
export ANDROID_SDK_ROOT=$HOME/Library/Android/sdk
|
||
export PATH=$PATH:$ANDROID_SDK_ROOT/emulator
|
||
export PATH=$PATH:$ANDROID_SDK_ROOT/platform-tools
|
||
```
|
||
|
||
创建一个新的应用程序
|
||
|
||
```bash
|
||
$ npx react-native init MyApp
|
||
# 指定 React Native 版本创建
|
||
$ npx react-native init MyApp --version X.XX.X
|
||
# 创建 typescript 版本项目
|
||
$ npx react-native init MyTSApp --template react-native-template-typescript
|
||
```
|
||
|
||
安装依赖
|
||
|
||
```bash
|
||
$ yarn install # 根目录运行
|
||
```
|
||
|
||
使用虚拟设备
|
||
|
||
- 使用 Android Studio 打开 <pur>./AwesomeProject/android</pur>
|
||
- 从 Android Studio 中打开 **AVD 管理器** 来查看可用的 Android **虚拟设备 (AVD)** 列表
|
||
- 第一次,您可能需要创建一个新的 AVD。选择 **Create Virtual Device...**,然后从列表中选择任何电话并单击“下一步”,然后选择 **S API Level 31 image**。
|
||
|
||
运行你的 React Native 应用程序
|
||
|
||
```bash
|
||
# 启动监听打包 JS 服务
|
||
$ npx react-native start
|
||
# 启动 iOS 模拟器运行你的应用
|
||
$ npx react-native run-ios
|
||
```
|
||
|
||
### 打开 React Native Debug 菜单
|
||
|
||
:- | --
|
||
:- | --
|
||
`⌘` + `M`(Android) | 打开<yel>开发者</yel>菜单
|
||
`⌘` + `D`(iOS) | 打开<yel>开发者</yel>菜单
|
||
`Ctrl` + `D`(Linux) | 打开<yel>开发者</yel>菜单
|
||
<pur>摇动您的设备</pur> | 打开<yel>开发者</yel>菜单
|
||
按两次 `R` 键 | 构建并运行
|
||
<!--rehype:className=shortcuts-->
|
||
|
||
基本组件
|
||
---
|
||
|
||
### View
|
||
|
||
```jsx
|
||
import React from "react";
|
||
import { View, Text } from "react-native";
|
||
|
||
export default function ViewExample() {
|
||
return (
|
||
<View
|
||
style={{
|
||
backgroundColor: "red",
|
||
flex: 0.5
|
||
}}
|
||
/>
|
||
);
|
||
};
|
||
```
|
||
|
||
构建 UI 的最基本组件
|
||
|
||
### Text
|
||
|
||
```jsx
|
||
import React from 'react';
|
||
import { Text } from 'react-native';
|
||
import { StyleSheet } from 'react-native';
|
||
|
||
export default function BoldBeautiful() {
|
||
return (
|
||
<Text style={styles.baseText}>
|
||
我是粗体
|
||
<Text style={styles.innerText}>
|
||
和红色
|
||
</Text>
|
||
</Text>
|
||
);
|
||
};
|
||
const styles = StyleSheet.create({
|
||
baseText: { fontWeight: 'bold' },
|
||
innerText: { color: 'red' }
|
||
});
|
||
```
|
||
|
||
用于显示文本的组件
|
||
|
||
### TextInput
|
||
|
||
```jsx
|
||
import React from "react";
|
||
import { SafeAreaView, StyleSheet, TextInput } from "react-native";
|
||
|
||
export default function UseTextInput() {
|
||
const [
|
||
text, onChangeText
|
||
] = React.useState("Useless Text");
|
||
return (
|
||
<SafeAreaView>
|
||
<TextInput
|
||
onChangeText={onChangeText}
|
||
value={text}
|
||
/>
|
||
</SafeAreaView>
|
||
);
|
||
};
|
||
```
|
||
<!--rehype:className=wrap-text-->
|
||
|
||
用于通过键盘将文本输入应用程序的组件
|
||
|
||
### Image
|
||
<!--rehype:wrap-class=col-span-2-->
|
||
|
||
```jsx
|
||
import React from 'react';
|
||
import { View, Image, StyleSheet } from 'react-native';
|
||
|
||
const styles = StyleSheet.create({
|
||
container: { paddingTop: 50, },
|
||
tinyLogo: { width: 50, height: 50, },
|
||
logo: { width: 66, height: 58, },
|
||
});
|
||
|
||
const DisplayAnImage = () => {
|
||
return (
|
||
<View style={styles.container}>
|
||
<Image
|
||
style={styles.tinyLogo}
|
||
source={require('@expo/snack-static/react-native-logo.png')}
|
||
/>
|
||
<Image
|
||
style={styles.tinyLogo}
|
||
source={{
|
||
uri: 'https://reactnative.dev/img/tiny_logo.png',
|
||
}}
|
||
/>
|
||
<Image
|
||
style={styles.logo}
|
||
source={{
|
||
uri: 'data:image/png;base64,iVBORw0K.....',
|
||
}}
|
||
/>
|
||
</View>
|
||
);
|
||
}
|
||
|
||
export default DisplayAnImage;
|
||
```
|
||
|
||
用于显示图像的组件
|
||
|
||
### ScrollView
|
||
|
||
```jsx
|
||
import React from 'react';
|
||
import { StyleSheet, Text, SafeAreaView, ScrollView, StatusBar } from 'react-native';
|
||
|
||
export const App = () => {
|
||
return (
|
||
<SafeAreaView style={styles.container}>
|
||
<ScrollView style={styles.scrollView}>
|
||
<Text style={styles.text}>
|
||
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
|
||
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||
Ut enim ad minim veniam, quis nostrud exercitation
|
||
ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
||
Duis aute irure dolor in reprehenderit in voluptate velit
|
||
esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
|
||
occaecat cupidatat non proident, sunt in culpa qui officia
|
||
deserunt mollit anim id est laborum.
|
||
</Text>
|
||
</ScrollView>
|
||
</SafeAreaView>
|
||
);
|
||
}
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
paddingTop: StatusBar.currentHeight,
|
||
},
|
||
scrollView: {
|
||
backgroundColor: 'pink',
|
||
marginHorizontal: 20,
|
||
},
|
||
text: {
|
||
fontSize: 42,
|
||
},
|
||
});
|
||
```
|
||
|
||
提供一个可以承载多个组件和视图的滚动容器
|
||
|
||
### StyleSheet
|
||
|
||
```jsx
|
||
import React from "react";
|
||
import { StyleSheet, Text, View } from "react-native";
|
||
|
||
export const App = () => (
|
||
<View style={styles.container}>
|
||
<Text style={styles.title}>
|
||
React Native
|
||
</Text>
|
||
</View>
|
||
);
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
padding: 24,
|
||
backgroundColor: "#eaeaea"
|
||
},
|
||
title: {
|
||
backgroundColor: "#61dafb",
|
||
color: "#20232a",
|
||
textAlign: "center",
|
||
}
|
||
});
|
||
```
|
||
<!--rehype:className=wrap-text-->
|
||
|
||
提供类似于 CSS 样式表的抽象层
|
||
|
||
用户界面
|
||
---
|
||
<!--rehype:body-class=cols-2-->
|
||
|
||
### Button
|
||
|
||
```jsx
|
||
import { Button } from "react-native";
|
||
|
||
<Button
|
||
onPress={onPressLearnMore}
|
||
title="Learn More"
|
||
color="#841584"
|
||
accessibilityLabel="了解紫色按钮的更多信息"
|
||
/>
|
||
```
|
||
|
||
一个基本的按钮组件,用于处理应该在任何平台上都能很好地呈现的触摸
|
||
|
||
### Switch
|
||
|
||
```jsx
|
||
import { Switch } from "react-native";
|
||
|
||
<Switch
|
||
trackColor={{ false: "#767577", true: "#81b0ff" }}
|
||
thumbColor={isEnabled ? "#f5dd4b" : "#f4f3f4"}
|
||
ios_backgroundColor="#3e3e3e"
|
||
onValueChange={toggleSwitch}
|
||
value={isEnabled}
|
||
/>
|
||
```
|
||
|
||
呈现布尔输入
|
||
|
||
列表视图
|
||
---
|
||
<!--rehype:body-class=cols-2-->
|
||
|
||
### SectionList
|
||
|
||
```jsx
|
||
import React from "react";
|
||
import {
|
||
StyleSheet, Text, View, SafeAreaView, SectionList, StatusBar
|
||
} from "react-native";
|
||
|
||
const DATA = [
|
||
{
|
||
title: "Main dishes",
|
||
data: ["Pizza", "Burger", "Risotto"]
|
||
},
|
||
{
|
||
title: "Sides",
|
||
data: ["French Fries", "Onion Rings", "Fried Shrimps"]
|
||
},
|
||
{
|
||
title: "Drinks",
|
||
data: ["Water", "Coke", "Beer"]
|
||
},
|
||
{
|
||
title: "Desserts",
|
||
data: ["Cheese Cake", "Ice Cream"]
|
||
}
|
||
];
|
||
|
||
const Item = ({ title }) => (
|
||
<View style={styles.item}>
|
||
<Text style={styles.title}>{title}</Text>
|
||
</View>
|
||
);
|
||
|
||
const App = () => (
|
||
<SafeAreaView style={styles.container}>
|
||
<SectionList
|
||
sections={DATA}
|
||
keyExtractor={(item, index) => item + index}
|
||
renderItem={({ item }) => <Item title={item} />}
|
||
renderSectionHeader={({ section: { title } }) => (
|
||
<Text style={styles.header}>{title}</Text>
|
||
)}
|
||
/>
|
||
</SafeAreaView>
|
||
);
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
paddingTop: StatusBar.currentHeight,
|
||
marginHorizontal: 16
|
||
},
|
||
item: {
|
||
backgroundColor: "#f9c2ff",
|
||
padding: 20,
|
||
marginVertical: 8
|
||
},
|
||
header: { fontSize: 32, backgroundColor: "#fff" },
|
||
title: { fontSize: 24 }
|
||
});
|
||
|
||
export default App;
|
||
```
|
||
|
||
### FlatList
|
||
|
||
```jsx
|
||
import React from 'react';
|
||
import {
|
||
SafeAreaView, View, FlatList, StyleSheet, Text, StatusBar
|
||
} from 'react-native';
|
||
|
||
const DATA = [
|
||
{
|
||
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
|
||
title: 'First Item',
|
||
},
|
||
{
|
||
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
|
||
title: 'Second Item',
|
||
},
|
||
{
|
||
id: '58694a0f-3da1-471f-bd96-145571e29d72',
|
||
title: 'Third Item',
|
||
},
|
||
];
|
||
|
||
const Item = ({ title }) => (
|
||
<View style={styles.item}>
|
||
<Text style={styles.title}>{title}</Text>
|
||
</View>
|
||
);
|
||
|
||
const App = () => {
|
||
const renderItem = ({ item }) => (
|
||
<Item title={item.title} />
|
||
);
|
||
|
||
return (
|
||
<SafeAreaView style={styles.container}>
|
||
<FlatList
|
||
data={DATA}
|
||
renderItem={renderItem}
|
||
keyExtractor={item => item.id}
|
||
/>
|
||
</SafeAreaView>
|
||
);
|
||
}
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
marginTop: StatusBar.currentHeight || 0,
|
||
},
|
||
item: {
|
||
backgroundColor: '#f9c2ff',
|
||
padding: 20,
|
||
marginVertical: 8,
|
||
marginHorizontal: 16,
|
||
},
|
||
title: {
|
||
fontSize: 32,
|
||
},
|
||
});
|
||
|
||
export default App;
|
||
```
|
||
|
||
Android 组件和 API
|
||
---
|
||
<!--rehype:body-class=cols-2-->
|
||
|
||
### BackHandler
|
||
|
||
```jsx
|
||
import React, { useEffect } from "react";
|
||
import {
|
||
Text, View, StyleSheet, BackHandler, Alert
|
||
} from "react-native";
|
||
|
||
const App = () => {
|
||
useEffect(() => {
|
||
const backAction = () => {
|
||
Alert.alert("Hold on!", "你确定要回去吗?", [
|
||
{
|
||
text: "Cancel",
|
||
onPress: () => null,
|
||
style: "cancel"
|
||
},
|
||
{ text: "YES", onPress: () => BackHandler.exitApp() }
|
||
]);
|
||
return true;
|
||
};
|
||
|
||
const backHandler = BackHandler.addEventListener(
|
||
"hardwareBackPress",
|
||
backAction
|
||
);
|
||
|
||
return () => backHandler.remove();
|
||
}, []);
|
||
|
||
return (
|
||
<View style={styles.container}>
|
||
<Text style={styles.text}>点击后退按钮!</Text>
|
||
</View>
|
||
);
|
||
};
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
alignItems: "center",
|
||
justifyContent: "center"
|
||
},
|
||
text: {
|
||
fontSize: 18,
|
||
fontWeight: "bold"
|
||
}
|
||
});
|
||
|
||
export default App;
|
||
```
|
||
|
||
检测硬件按钮按下以进行后退导航
|
||
|
||
### DrawerLayoutAndroid
|
||
|
||
```jsx
|
||
import React, { useRef, useState } from "react";
|
||
import {
|
||
Button, DrawerLayoutAndroid, Text, StyleSheet, View
|
||
} from "react-native";
|
||
|
||
const App = () => {
|
||
const drawer = useRef(null);
|
||
const [drawerPosition, setDrawerPosition] = useState("left");
|
||
const changeDrawerPosition = () => {
|
||
if (drawerPosition === "left") {
|
||
setDrawerPosition("right");
|
||
} else {
|
||
setDrawerPosition("left");
|
||
}
|
||
};
|
||
|
||
const navigationView = () => (
|
||
<View style={[styles.container, styles.navigationContainer]}>
|
||
<Text style={styles.paragraph}>I'm in the Drawer!</Text>
|
||
<Button
|
||
title="Close drawer"
|
||
onPress={() => drawer.current.closeDrawer()}
|
||
/>
|
||
</View>
|
||
);
|
||
|
||
return (
|
||
<DrawerLayoutAndroid
|
||
ref={drawer}
|
||
drawerWidth={300}
|
||
drawerPosition={drawerPosition}
|
||
renderNavigationView={navigationView}
|
||
>
|
||
<View style={styles.container}>
|
||
<Text style={styles.paragraph}>
|
||
Drawer on the {drawerPosition}!
|
||
</Text>
|
||
<Button
|
||
title="Change Drawer Position"
|
||
onPress={() => changeDrawerPosition()}
|
||
/>
|
||
<Text style={styles.paragraph}>
|
||
Swipe from the side or press button below to see it!
|
||
</Text>
|
||
<Button
|
||
title="Open drawer"
|
||
onPress={() => drawer.current.openDrawer()}
|
||
/>
|
||
</View>
|
||
</DrawerLayoutAndroid>
|
||
);
|
||
};
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
alignItems: "center",
|
||
justifyContent: "center",
|
||
padding: 16
|
||
},
|
||
navigationContainer: {
|
||
backgroundColor: "#ecf0f1"
|
||
},
|
||
paragraph: {
|
||
padding: 16,
|
||
fontSize: 15,
|
||
textAlign: "center"
|
||
}
|
||
});
|
||
|
||
export default App;
|
||
```
|
||
|
||
在 Android 上呈现 DrawerLayout
|
||
|
||
### PermissionsAndroid
|
||
|
||
```jsx
|
||
import React from "react";
|
||
import {
|
||
Button, PermissionsAndroid,
|
||
SafeAreaView, StatusBar, StyleSheet, Text, View
|
||
} from "react-native";
|
||
|
||
const requestCameraPermission = async () => {
|
||
try {
|
||
const granted = await PermissionsAndroid.request(
|
||
PermissionsAndroid.PERMISSIONS.CAMERA,
|
||
{
|
||
title: "Cool Photo App Camera Permission",
|
||
message:
|
||
"Cool Photo App needs access to your camera " +
|
||
"so you can take awesome pictures.",
|
||
buttonNeutral: "Ask Me Later",
|
||
buttonNegative: "Cancel",
|
||
buttonPositive: "OK"
|
||
}
|
||
);
|
||
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
|
||
console.log("You can use the camera");
|
||
} else {
|
||
console.log("Camera permission denied");
|
||
}
|
||
} catch (err) {
|
||
console.warn(err);
|
||
}
|
||
};
|
||
|
||
const App = () => (
|
||
<View style={styles.container}>
|
||
<Text style={styles.item}>Try permissions</Text>
|
||
<Button
|
||
title="request permissions"
|
||
onPress={requestCameraPermission}
|
||
/>
|
||
</View>
|
||
);
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
justifyContent: "center",
|
||
paddingTop: StatusBar.currentHeight,
|
||
backgroundColor: "#ecf0f1",
|
||
padding: 8
|
||
},
|
||
item: {
|
||
margin: 24,
|
||
fontSize: 18,
|
||
fontWeight: "bold",
|
||
textAlign: "center"
|
||
}
|
||
});
|
||
|
||
export default App;
|
||
```
|
||
|
||
提供对 Android M 中引入的权限模型的访问
|
||
|
||
### ToastAndroid
|
||
|
||
```jsx
|
||
import React from "react";
|
||
import {
|
||
View, StyleSheet, ToastAndroid, Button, StatusBar
|
||
} from "react-native";
|
||
|
||
const App = () => {
|
||
const showToast = () => {
|
||
ToastAndroid.show("一只皮卡丘出现在附近!", ToastAndroid.SHORT);
|
||
};
|
||
|
||
const showToastWithGravity = () => {
|
||
ToastAndroid.showWithGravity(
|
||
"All Your Base Are Belong To Us",
|
||
ToastAndroid.SHORT,
|
||
ToastAndroid.CENTER
|
||
);
|
||
};
|
||
|
||
const showToastWithGravityAndOffset = () => {
|
||
ToastAndroid.showWithGravityAndOffset(
|
||
"A wild toast appeared!",
|
||
ToastAndroid.LONG,
|
||
ToastAndroid.BOTTOM,
|
||
25,
|
||
50
|
||
);
|
||
};
|
||
|
||
return (
|
||
<View style={styles.container}>
|
||
<Button title="Toggle Toast" onPress={() => showToast()} />
|
||
<Button
|
||
title="Toggle Toast With Gravity"
|
||
onPress={() => showToastWithGravity()}
|
||
/>
|
||
<Button
|
||
title="Toggle Toast With Gravity & Offset"
|
||
onPress={() => showToastWithGravityAndOffset()}
|
||
/>
|
||
</View>
|
||
);
|
||
};
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
justifyContent: "center",
|
||
paddingTop: StatusBar.currentHeight,
|
||
backgroundColor: "#888888",
|
||
padding: 8
|
||
}
|
||
});
|
||
|
||
export default App;
|
||
```
|
||
|
||
创建 Android Toast 警报
|
||
|
||
iOS 组件和 API
|
||
---
|
||
<!--rehype:body-class=cols-1-->
|
||
|
||
### ActionSheetIOS
|
||
|
||
```jsx
|
||
import React, { useState } from "react";
|
||
import { ActionSheetIOS, Button, StyleSheet, Text, View } from "react-native";
|
||
|
||
const App = () => {
|
||
const [result, setResult] = useState("🔮");
|
||
|
||
const onPress = () =>
|
||
ActionSheetIOS.showActionSheetWithOptions(
|
||
{
|
||
options: ["Cancel", "Generate number", "Reset"],
|
||
destructiveButtonIndex: 2,
|
||
cancelButtonIndex: 0,
|
||
userInterfaceStyle: 'dark'
|
||
},
|
||
buttonIndex => {
|
||
if (buttonIndex === 0) {
|
||
// cancel action
|
||
} else if (buttonIndex === 1) {
|
||
setResult(Math.floor(Math.random() * 100) + 1);
|
||
} else if (buttonIndex === 2) {
|
||
setResult("🔮");
|
||
}
|
||
}
|
||
);
|
||
|
||
return (
|
||
<View style={styles.container}>
|
||
<Text style={styles.result}>{result}</Text>
|
||
<Button onPress={onPress} title="Show Action Sheet" />
|
||
</View>
|
||
);
|
||
};
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
justifyContent: "center"
|
||
},
|
||
result: {
|
||
fontSize: 64,
|
||
textAlign: "center"
|
||
}
|
||
});
|
||
|
||
export default App;
|
||
```
|
||
|
||
其它
|
||
---
|
||
<!--rehype:body-class=cols-2-->
|
||
|
||
### ActivityIndicator
|
||
|
||
```jsx
|
||
import React from "react";
|
||
import {
|
||
ActivityIndicator, StyleSheet, Text, View
|
||
} from "react-native";
|
||
|
||
const App = () => (
|
||
<View style={[styles.container, styles.horizontal]}>
|
||
<ActivityIndicator />
|
||
<ActivityIndicator size="large" />
|
||
<ActivityIndicator size="small" color="#0000ff" />
|
||
<ActivityIndicator size="large" color="#00ff00" />
|
||
</View>
|
||
);
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
justifyContent: "center"
|
||
},
|
||
horizontal: {
|
||
flexDirection: "row",
|
||
justifyContent: "space-around",
|
||
padding: 10
|
||
}
|
||
});
|
||
|
||
export default App;
|
||
```
|
||
|
||
显示圆形加载指示器
|
||
|
||
### Alert
|
||
|
||
```jsx
|
||
import React, { useState } from "react";
|
||
import { View, StyleSheet, Button, Alert } from "react-native";
|
||
|
||
const App = () => {
|
||
const createTwoButtonAlert = () =>
|
||
Alert.alert( "Alert Title", "My Alert Msg",
|
||
[
|
||
{
|
||
text: "Cancel",
|
||
onPress: () => console.log("Cancel Pressed"),
|
||
style: "cancel"
|
||
},
|
||
{ text: "OK", onPress: () => console.log("OK Pressed") }
|
||
]
|
||
);
|
||
|
||
return (
|
||
<View style={styles.container}>
|
||
<Button title={"2-Button Alert"}
|
||
onPress={createTwoButtonAlert} />
|
||
</View>
|
||
);
|
||
}
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
justifyContent: "space-around",
|
||
alignItems: "center"
|
||
}
|
||
});
|
||
|
||
export default App;
|
||
```
|
||
|
||
启动具有指定标题和消息的警报对话框
|
||
|
||
### Animated
|
||
<!--rehype:wrap-class=row-span-2-->
|
||
|
||
```jsx
|
||
import React, { useRef } from "react";
|
||
import {
|
||
Animated, Text, View, StyleSheet, Button, SafeAreaView
|
||
} from "react-native";
|
||
|
||
const App = () => {
|
||
// fadeAnim 将用作不透明度的值。 初始值:0
|
||
const fadeAnim = useRef(new Animated.Value(0)).current;
|
||
const fadeIn = () => {
|
||
// 将在 5 秒内将 fadeAnim 值更改为 1
|
||
Animated.timing(fadeAnim, {
|
||
toValue: 1,
|
||
duration: 5000
|
||
}).start();
|
||
};
|
||
const fadeOut = () => {
|
||
// 将在 3 秒内将 fadeAnim 值更改为 0
|
||
Animated.timing(fadeAnim, {
|
||
toValue: 0,
|
||
duration: 3000
|
||
}).start();
|
||
};
|
||
return (
|
||
<SafeAreaView style={styles.container}>
|
||
<Animated.View
|
||
style={[
|
||
styles.fadingContainer,
|
||
{
|
||
// 将不透明度绑定到动画值
|
||
opacity: fadeAnim
|
||
}
|
||
]}
|
||
>
|
||
<Text style={styles.fadingText}>Fading View!</Text>
|
||
</Animated.View>
|
||
<View style={styles.buttonRow}>
|
||
<Button title="淡入淡出" onPress={fadeIn} />
|
||
<Button title="淡出视图" onPress={fadeOut} />
|
||
</View>
|
||
</SafeAreaView>
|
||
);
|
||
}
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
alignItems: "center",
|
||
justifyContent: "center"
|
||
},
|
||
fadingContainer: {
|
||
padding: 20,
|
||
backgroundColor: "powderblue"
|
||
},
|
||
fadingText: { fontSize: 28 },
|
||
buttonRow: {
|
||
flexBasis: 100,
|
||
justifyContent: "space-evenly",
|
||
marginVertical: 16
|
||
}
|
||
});
|
||
|
||
export default App;
|
||
```
|
||
|
||
一个用于创建易于构建和维护的流畅、强大的动画的库
|
||
|
||
### Dimensions
|
||
|
||
```jsx
|
||
import { Dimensions } from 'react-native';
|
||
|
||
const windowWidth = Dimensions.get('window').width;
|
||
const windowHeight = Dimensions.get('window').height;
|
||
```
|
||
|
||
提供获取设备尺寸的接口
|
||
|
||
### KeyboardAvoidingView
|
||
|
||
```jsx
|
||
import React from 'react';
|
||
import {
|
||
View, KeyboardAvoidingView, TextInput,
|
||
StyleSheet, Text, Platform,
|
||
TouchableWithoutFeedback, Button, Keyboard
|
||
} from 'react-native';
|
||
|
||
const KeyboardAvoidingComponent = () => {
|
||
return (
|
||
<KeyboardAvoidingView
|
||
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
||
style={styles.container}
|
||
>
|
||
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
||
<View style={styles.inner}>
|
||
<Text style={styles.header}>Header</Text>
|
||
<TextInput placeholder="用户名" style={styles.textInput} />
|
||
<View style={styles.btnContainer}>
|
||
<Button title="Submit" onPress={() => null} />
|
||
</View>
|
||
</View>
|
||
</TouchableWithoutFeedback>
|
||
</KeyboardAvoidingView>
|
||
);
|
||
};
|
||
|
||
const styles = StyleSheet.create({
|
||
container: { flex: 1 },
|
||
inner: {
|
||
padding: 24,
|
||
flex: 1,
|
||
justifyContent: "space-around"
|
||
},
|
||
header: { fontSize: 36, marginBottom: 48 },
|
||
textInput: {
|
||
height: 40,
|
||
borderColor: "#000000",
|
||
borderBottomWidth: 1,
|
||
marginBottom: 36
|
||
},
|
||
btnContainer: {
|
||
backgroundColor: "white",
|
||
marginTop: 12
|
||
}
|
||
});
|
||
|
||
export default KeyboardAvoidingComponent;
|
||
```
|
||
|
||
提供一个自动移出虚拟键盘的视图
|
||
|
||
### Linking
|
||
|
||
```jsx
|
||
import React, { useCallback } from "react";
|
||
import {
|
||
Alert, Button, Linking, StyleSheet, View
|
||
} from "react-native";
|
||
|
||
const supportedURL = "https://google.com";
|
||
const unsupportedURL = "slack://open?team=123456";
|
||
const OpenURLButton = ({ url, children }) => {
|
||
const handlePress = useCallback(async () => {
|
||
// 检查具有自定义 URL 方案的链接是否支持该链接。
|
||
const supported = await Linking.canOpenURL(url);
|
||
if (supported) {
|
||
// 打开某些应用程序的链接,如果 URL 方案是“http”,则应打开 Web 链接
|
||
// 通过手机中的某些浏览器
|
||
await Linking.openURL(url);
|
||
} else {
|
||
Alert.alert(`不知道如何打开这个网址: ${url}`);
|
||
}
|
||
}, [url]);
|
||
return <Button title={children} onPress={handlePress} />;
|
||
};
|
||
|
||
export default function App() {
|
||
return (
|
||
<View style={styles.container}>
|
||
<OpenURLButton url={supportedURL}>
|
||
打开支持的 URL
|
||
</OpenURLButton>
|
||
<OpenURLButton url={unsupportedURL}>
|
||
打开不支持的 URL
|
||
</OpenURLButton>
|
||
</View>
|
||
);
|
||
};
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
justifyContent: "center",
|
||
alignItems: "center"
|
||
},
|
||
});
|
||
```
|
||
|
||
提供一个通用接口来与传入和传出应用程序链接进行交互
|
||
|
||
### Modal
|
||
<!--rehype:wrap-class=row-span-3-->
|
||
|
||
```jsx
|
||
import React, { useState } from "react";
|
||
import {
|
||
Alert, Modal, StyleSheet, Text, Pressable, View
|
||
} from "react-native";
|
||
|
||
const App = () => {
|
||
const [modalVisible, setModalVisible] = useState(false);
|
||
return (
|
||
<View style={styles.centeredView}>
|
||
<Modal
|
||
animationType="slide"
|
||
transparent={true}
|
||
visible={modalVisible}
|
||
onRequestClose={() => {
|
||
Alert.alert("模态已关闭");
|
||
setModalVisible(!modalVisible);
|
||
}}
|
||
>
|
||
<View style={styles.centeredView}>
|
||
<View style={styles.modalView}>
|
||
<Text style={styles.modalText}>Hello World!</Text>
|
||
<Pressable
|
||
style={[styles.button, styles.buttonClose]}
|
||
onPress={() => setModalVisible(!modalVisible)}
|
||
>
|
||
<Text style={styles.textStyle}>Hide Modal</Text>
|
||
</Pressable>
|
||
</View>
|
||
</View>
|
||
</Modal>
|
||
<Pressable
|
||
style={[styles.button, styles.buttonOpen]}
|
||
onPress={() => setModalVisible(true)}
|
||
>
|
||
<Text style={styles.textStyle}>Show Modal</Text>
|
||
</Pressable>
|
||
</View>
|
||
);
|
||
};
|
||
|
||
const styles = StyleSheet.create({
|
||
centeredView: {
|
||
flex: 1,
|
||
justifyContent: "center",
|
||
alignItems: "center",
|
||
marginTop: 22
|
||
},
|
||
modalView: {
|
||
margin: 20,
|
||
backgroundColor: "white",
|
||
borderRadius: 20,
|
||
padding: 35,
|
||
alignItems: "center",
|
||
shadowColor: "#000",
|
||
shadowOffset: {
|
||
width: 0,
|
||
height: 2
|
||
},
|
||
shadowOpacity: 0.25,
|
||
shadowRadius: 4,
|
||
elevation: 5
|
||
},
|
||
button: {
|
||
borderRadius: 20,
|
||
padding: 10,
|
||
elevation: 2
|
||
},
|
||
buttonOpen: {
|
||
backgroundColor: "#F194FF",
|
||
},
|
||
buttonClose: {
|
||
backgroundColor: "#2196F3",
|
||
},
|
||
textStyle: {
|
||
color: "white",
|
||
fontWeight: "bold",
|
||
textAlign: "center"
|
||
},
|
||
modalText: {
|
||
marginBottom: 15,
|
||
textAlign: "center"
|
||
}
|
||
});
|
||
|
||
export default App;
|
||
```
|
||
|
||
提供一种在封闭视图上方呈现内容的简单方法
|
||
|
||
### PixelRatio
|
||
|
||
```jsx
|
||
var image = getImage({
|
||
width: PixelRatio.getPixelSizeForLayoutSize(200),
|
||
height: PixelRatio.getPixelSizeForLayoutSize(100)
|
||
});
|
||
<Image source={image} style={{ width: 200, height: 100 }} />;
|
||
```
|
||
|
||
提供对设备像素密度的访问
|
||
|
||
### RefreshControl
|
||
|
||
```jsx
|
||
import React from 'react';
|
||
import {
|
||
RefreshControl, SafeAreaView, ScrollView, StyleSheet, Text
|
||
} from 'react-native';
|
||
const wait = (timeout) => {
|
||
return new Promise(resolve => setTimeout(resolve, timeout));
|
||
}
|
||
export default function App() {
|
||
const [refreshing, setRefreshing] = React.useState(false);
|
||
const onRefresh = React.useCallback(() => {
|
||
setRefreshing(true);
|
||
wait(2000).then(() => setRefreshing(false));
|
||
}, []);
|
||
return (
|
||
<SafeAreaView style={styles.container}>
|
||
<ScrollView
|
||
contentContainerStyle={styles.scrollView}
|
||
refreshControl={
|
||
<RefreshControl
|
||
refreshing={refreshing}
|
||
onRefresh={onRefresh}
|
||
/>
|
||
}
|
||
>
|
||
<Text>下拉看 RefreshControl 指标</Text>
|
||
</ScrollView>
|
||
</SafeAreaView>
|
||
);
|
||
}
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
},
|
||
scrollView: {
|
||
flex: 1,
|
||
backgroundColor: 'pink',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
},
|
||
});
|
||
```
|
||
|
||
该组件在 ScrollView 内部使用,以添加下拉刷新功能
|
||
|
||
### StatusBar
|
||
<!--rehype:wrap-class=col-span-2-->
|
||
|
||
```jsx
|
||
import React, { useState } from 'react';
|
||
import { Button, Platform, SafeAreaView, StatusBar, StyleSheet, Text, View } from 'react-native';
|
||
|
||
const STYLES = ['default', 'dark-content', 'light-content'];
|
||
const TRANSITIONS = ['fade', 'slide', 'none'];
|
||
|
||
const App = () => {
|
||
const [hidden, setHidden] = useState(false);
|
||
const [statusBarStyle, setStatusBarStyle] = useState(STYLES[0]);
|
||
const [statusBarTransition, setStatusBarTransition] = useState(TRANSITIONS[0]);
|
||
|
||
const changeStatusBarVisibility = () => setHidden(!hidden);
|
||
|
||
const changeStatusBarStyle = () => {
|
||
const styleId = STYLES.indexOf(statusBarStyle) + 1;
|
||
if (styleId === STYLES.length) {
|
||
setStatusBarStyle(STYLES[0]);
|
||
} else {
|
||
setStatusBarStyle(STYLES[styleId]);
|
||
}
|
||
};
|
||
|
||
const changeStatusBarTransition = () => {
|
||
const transition = TRANSITIONS.indexOf(statusBarTransition) + 1;
|
||
if (transition === TRANSITIONS.length) {
|
||
setStatusBarTransition(TRANSITIONS[0]);
|
||
} else {
|
||
setStatusBarTransition(TRANSITIONS[transition]);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<SafeAreaView style={styles.container}>
|
||
<StatusBar
|
||
animated={true}
|
||
backgroundColor="#61dafb"
|
||
barStyle={statusBarStyle}
|
||
showHideTransition={statusBarTransition}
|
||
hidden={hidden} />
|
||
<Text style={styles.textStyle}>
|
||
StatusBar Visibility:{'\n'}
|
||
{hidden ? 'Hidden' : 'Visible'}
|
||
</Text>
|
||
<Text style={styles.textStyle}>
|
||
StatusBar Style:{'\n'}
|
||
{statusBarStyle}
|
||
</Text>
|
||
{Platform.OS === 'ios' ? (
|
||
<Text style={styles.textStyle}>
|
||
StatusBar Transition:{'\n'}
|
||
{statusBarTransition}
|
||
</Text>
|
||
) : null}
|
||
<View style={styles.buttonsContainer}>
|
||
<Button
|
||
title="Toggle StatusBar"
|
||
onPress={changeStatusBarVisibility} />
|
||
<Button
|
||
title="Change StatusBar Style"
|
||
onPress={changeStatusBarStyle} />
|
||
{Platform.OS === 'ios' ? (
|
||
<Button
|
||
title="Change StatusBar Transition"
|
||
onPress={changeStatusBarTransition} />
|
||
) : null}
|
||
</View>
|
||
</SafeAreaView>
|
||
);
|
||
};
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
justifyContent: 'center',
|
||
backgroundColor: '#ECF0F1'
|
||
},
|
||
buttonsContainer: {
|
||
padding: 10
|
||
},
|
||
textStyle: {
|
||
textAlign: 'center',
|
||
marginBottom: 8
|
||
}
|
||
});
|
||
|
||
export default App;
|
||
```
|
||
|
||
控制应用程序状态栏的组件
|
||
|
||
StyleSheet
|
||
----
|
||
|
||
### StyleSheet
|
||
|
||
```jsx
|
||
import { StyleSheet } from 'react-native';
|
||
|
||
const styles = StyleSheet.create({
|
||
paragraph: {
|
||
fontSize: 16,
|
||
},
|
||
label: {
|
||
fontSize: 11,
|
||
textTransform: 'uppercase'
|
||
}
|
||
});
|
||
|
||
<Text style={styles.paragraph}>段落</Text>
|
||
<Text style={styles.label}>标签</Text>
|
||
```
|
||
|
||
StyleSheet 是一种抽象,它通过使用二维 JavaScript 对象接受 CSS 样式规则来替代 CSS
|
||
|
||
### style 属性
|
||
|
||
```jsx
|
||
<Text style={styles.paragraph} />
|
||
<Text style={{ fontSize: 16 }} />
|
||
<Text
|
||
style={[
|
||
styles.paragraph, { color: 'red' }
|
||
]}
|
||
/>
|
||
```
|
||
|
||
可以使用 `style={}` 属性设置组件的样式,该属性接受对象作为内联样式、样式表创建的样式定义或一组对象/定义来组成样式
|
||
|
||
### 使用样式表定义
|
||
|
||
```jsx
|
||
// 使用内联样式
|
||
const AwesomeBox = () => (
|
||
<View style={{
|
||
width: 100, height: 100,
|
||
backgroundColor: 'red' }} />
|
||
);
|
||
// 使用样式表 API
|
||
const AwesomeBox = () => (
|
||
<View style={styles.box} />
|
||
);
|
||
|
||
const styles = StyleSheet.create({
|
||
box: {
|
||
width: 100,
|
||
height: 100,
|
||
backgroundColor: 'red'
|
||
},
|
||
});
|
||
```
|
||
|
||
### 动态样式
|
||
|
||
```jsx
|
||
// 如果 props.isActive 为真 则在 `paragraph`
|
||
// 样式之上应用 `selected` 样式
|
||
function Item(props) {
|
||
return (
|
||
<Text style={[
|
||
styles.paragraph,
|
||
props.isActive && styles.selected
|
||
]} />
|
||
);
|
||
}
|
||
```
|
||
|
||
### React Native 中的 Flex
|
||
|
||
```jsx
|
||
<View style={{ flexDirection: 'row' }}>
|
||
<View style={{ flex: 1 }} />
|
||
<View style={{ flex: 1 }} />
|
||
<View style={{ flex: 1 }} />
|
||
</View>
|
||
```
|
||
|
||
布局是用类似 `Flex` 的规则定义的,以适应各种屏幕尺寸。Web 上的 `Flex` 和 React Native 中的 `Flex` 之间的主要区别在于不需要带有 `display: flex` 的父元素
|
||
|
||
### flexDirection
|
||
|
||
```jsx
|
||
<View style={{ flexDirection: 'row' }}>
|
||
<View style={{ flex: 1 }} />
|
||
<View style={{ flex: 1 }} />
|
||
<View style={{ flex: 1 }} />
|
||
</View>
|
||
```
|
||
|
||
flexDirection 样式属性确定子元素的布局方向和顺序,可以是`row`、`row-reverse`、`column`或`column-reverse`
|
||
|
||
### justifyContent
|
||
|
||
```jsx
|
||
<View style={{
|
||
flexDirection: 'row',
|
||
justifyContent: 'flex-start'
|
||
}}>
|
||
<View style={{ flex: 1 }} />
|
||
<View style={{ flex: 1 }} />
|
||
<View style={{ flex: 1 }} />
|
||
</View>
|
||
```
|
||
|
||
样式属性决定了子元素在父容器中的定位方式,可以是 `center`、`flex-start`、`flex-end`、`space-around`、`space-between` 或 `space-evenly`。
|
||
|
||
### React Native 中的尺寸
|
||
|
||
```jsx
|
||
<View
|
||
style={{
|
||
width: 50,
|
||
height: 50,
|
||
backgroundColor: 'powderblue'
|
||
}}
|
||
/>
|
||
```
|
||
|
||
默认所有尺寸都是<pur>**无单位**</pur>的,并且表示与密度无关的像素
|
||
|
||
Props
|
||
---
|
||
|
||
### View Style Props
|
||
<!--rehype:wrap-class=row-span-3-->
|
||
|
||
```jsx
|
||
import React from "react";
|
||
import { View, StyleSheet } from "react-native";
|
||
|
||
export default function ViewStyle() {
|
||
return (
|
||
<View style={styles.container}>
|
||
</View>
|
||
);
|
||
}
|
||
|
||
const styles = StyleSheet.create({
|
||
container: {
|
||
flex: 1,
|
||
justifyContent: "space-between",
|
||
backgroundColor: "#fff",
|
||
},
|
||
});
|
||
```
|
||
<!--rehype:className=wrap-text-->
|
||
|
||
---
|
||
|
||
:- | --
|
||
:- | --
|
||
`backfaceVisibility` | [#](https://reactnative.dev/docs/view-style-props#backfacevisibility)
|
||
`backgroundColor` | [#](https://reactnative.dev/docs/view-style-props#backgroundcolor)
|
||
`borderBottomColor` | [#](https://reactnative.dev/docs/view-style-props#borderbottomcolor)
|
||
`borderBottomEndRadius` | [#](https://reactnative.dev/docs/view-style-props#borderbottomendradius)
|
||
`borderBottomLeftRadius` | [#](https://reactnative.dev/docs/view-style-props#borderbottomleftradius)
|
||
`borderBottomRightRadius` | [#](https://reactnative.dev/docs/view-style-props#borderbottomrightradius)
|
||
`borderBottomStartRadius` | [#](https://reactnative.dev/docs/view-style-props#borderbottomstartradius)
|
||
`borderBottomWidth` | [#](https://reactnative.dev/docs/view-style-props#borderbottomwidth)
|
||
`borderColor` | [#](https://reactnative.dev/docs/view-style-props#bordercolor)
|
||
`borderEndColor` | [#](https://reactnative.dev/docs/view-style-props#borderendcolor)
|
||
`borderLeftColor` | [#](https://reactnative.dev/docs/view-style-props#borderleftcolor)
|
||
`borderLeftWidth` | [#](https://reactnative.dev/docs/view-style-props#borderleftwidth)
|
||
`borderRadius` | [#](https://reactnative.dev/docs/view-style-props#borderradius)
|
||
`borderRightColor` | [#](https://reactnative.dev/docs/view-style-props#borderrightcolor)
|
||
`borderRightWidth` | [#](https://reactnative.dev/docs/view-style-props#borderrightwidth)
|
||
`borderStartColor` | [#](https://reactnative.dev/docs/view-style-props#borderstartcolor)
|
||
`borderStyle` | [#](https://reactnative.dev/docs/view-style-props#borderstyle)
|
||
`borderTopColor` | [#](https://reactnative.dev/docs/view-style-props#bordertopcolor)
|
||
`borderTopEndRadius` | [#](https://reactnative.dev/docs/view-style-props#bordertopendradius)
|
||
`borderTopLeftRadius` | [#](https://reactnative.dev/docs/view-style-props#bordertopleftradius)
|
||
`borderTopRightRadius` | [#](https://reactnative.dev/docs/view-style-props#bordertoprightradius)
|
||
`borderTopStartRadius` | [#](https://reactnative.dev/docs/view-style-props#bordertopstartradius)
|
||
`borderTopWidth` | [#](https://reactnative.dev/docs/view-style-props#bordertopwidth)
|
||
`borderWidth` | [#](https://reactnative.dev/docs/view-style-props#borderwidth)
|
||
`elevation` _Android_ | [#](https://reactnative.dev/docs/view-style-props#elevation-android)
|
||
`opacity` | [#](https://reactnative.dev/docs/view-style-props#opacity)
|
||
|
||
### Text Style Props
|
||
<!--rehype:wrap-class=row-span-2-->
|
||
|
||
:- | --
|
||
:- | --
|
||
`color` | [#](https://reactnative.dev/docs/text-style-props#color)
|
||
`fontFamily` | [#](https://reactnative.dev/docs/text-style-props#fontfamily)
|
||
`fontSize` | [#](https://reactnative.dev/docs/text-style-props#fontsize)
|
||
`fontStyle` | [#](https://reactnative.dev/docs/text-style-props#fontstyle)
|
||
`fontWeight` | [#](https://reactnative.dev/docs/text-style-props#fontweight)
|
||
`includeFontPadding` _Android_ | [#](https://reactnative.dev/docs/text-style-props#includefontpadding-android)
|
||
`fontVariant` | [#](https://reactnative.dev/docs/text-style-props#fontvariant)
|
||
`letterSpacing` | [#](https://reactnative.dev/docs/text-style-props#letterspacing)
|
||
`lineHeight` | [#](https://reactnative.dev/docs/text-style-props#lineheight)
|
||
`textAlign` | [#](https://reactnative.dev/docs/text-style-props#textalign)
|
||
`textAlignVertical` _Android_ | [#](https://reactnative.dev/docs/text-style-props#textalignvertical-android)
|
||
`textDecorationColor` _iOS_ | [#](https://reactnative.dev/docs/text-style-props#textdecorationcolor-ios)
|
||
`textDecorationLine` | [#](https://reactnative.dev/docs/text-style-props#textdecorationline)
|
||
`textDecorationStyle` _iOS_ | [#](https://reactnative.dev/docs/text-style-props#textdecorationstyle-ios)
|
||
`textShadowColor` | [#](https://reactnative.dev/docs/text-style-props#textshadowcolor)
|
||
`textShadowOffset` | [#](https://reactnative.dev/docs/text-style-props#textshadowoffset)
|
||
`textShadowRadius` | [#](https://reactnative.dev/docs/text-style-props#textshadowradius)
|
||
`textTransform` | [#](https://reactnative.dev/docs/text-style-props#texttransform)
|
||
`writingDirection` _iOS_ | [#](https://reactnative.dev/docs/text-style-props#writingdirection-ios)
|
||
|
||
### Shadow Props
|
||
|
||
:- | --
|
||
:- | --
|
||
`shadowColor` | [#](https://reactnative.dev/docs/shadow-props#shadowcolor)
|
||
`shadowOffset` _iOS_ | [#](https://reactnative.dev/docs/shadow-props#shadowoffset-ios)
|
||
`shadowOpacity` _iOS_ | [#](https://reactnative.dev/docs/shadow-props#shadowopacity-ios)
|
||
`shadowRadius` _iOS_ | [#](https://reactnative.dev/docs/shadow-props#shadowradius-ios)
|
||
|
||
### Layout Props
|
||
<!--rehype:wrap-class=row-span-3-->
|
||
|
||
:- | --
|
||
:- | --
|
||
`alignContent` | [#](https://reactnative.dev/docs/layout-props#aligncontent)
|
||
`alignItems` | [#](https://reactnative.dev/docs/layout-props#alignitems)
|
||
`alignSelf` | [#](https://reactnative.dev/docs/layout-props#alignself)
|
||
`aspectRatio` | [#](https://reactnative.dev/docs/layout-props#aspectratio)
|
||
`borderBottomWidth` | [#](https://reactnative.dev/docs/layout-props#borderbottomwidth)
|
||
`borderEndWidth` | [#](https://reactnative.dev/docs/layout-props#borderendwidth)
|
||
`borderLeftWidth` | [#](https://reactnative.dev/docs/layout-props#borderleftwidth)
|
||
`borderRightWidth` | [#](https://reactnative.dev/docs/layout-props#borderrightwidth)
|
||
`borderStartWidth` | [#](https://reactnative.dev/docs/layout-props#borderstartwidth)
|
||
`borderTopWidth` | [#](https://reactnative.dev/docs/layout-props#bordertopwidth)
|
||
`borderWidth` | [#](https://reactnative.dev/docs/layout-props#borderwidth)
|
||
`bottom` | [#](https://reactnative.dev/docs/layout-props#bottom)
|
||
`direction` | [#](https://reactnative.dev/docs/layout-props#direction)
|
||
`display` | [#](https://reactnative.dev/docs/layout-props#display)
|
||
`end` | [#](https://reactnative.dev/docs/layout-props#end)
|
||
`flex` | [#](https://reactnative.dev/docs/layout-props#flex)
|
||
`flexBasis` | [#](https://reactnative.dev/docs/layout-props#flexbasis)
|
||
`flexDirection` | [#](https://reactnative.dev/docs/layout-props#flexdirection)
|
||
`flexGrow` | [#](https://reactnative.dev/docs/layout-props#flexgrow)
|
||
`flexShrink` | [#](https://reactnative.dev/docs/layout-props#flexshrink)
|
||
`flexWrap` | [#](https://reactnative.dev/docs/layout-props#flexwrap)
|
||
`height` | [#](https://reactnative.dev/docs/layout-props#height)
|
||
`justifyContent` | [#](https://reactnative.dev/docs/layout-props#justifycontent)
|
||
`left` | [#](https://reactnative.dev/docs/layout-props#left)
|
||
`margin` | [#](https://reactnative.dev/docs/layout-props#margin)
|
||
`marginBottom` | [#](https://reactnative.dev/docs/layout-props#marginbottom)
|
||
`marginEnd` | [#](https://reactnative.dev/docs/layout-props#marginend)
|
||
`marginHorizontal` | [#](https://reactnative.dev/docs/layout-props#marginhorizontal)
|
||
`marginLeft` | [#](https://reactnative.dev/docs/layout-props#marginleft)
|
||
`marginRight` | [#](https://reactnative.dev/docs/layout-props#marginright)
|
||
`marginStart` | [#](https://reactnative.dev/docs/layout-props#marginstart)
|
||
`marginTop` | [#](https://reactnative.dev/docs/layout-props#margintop)
|
||
`marginVertical` | [#](https://reactnative.dev/docs/layout-props#marginvertical)
|
||
`maxHeight` | [#](https://reactnative.dev/docs/layout-props#maxheight)
|
||
`maxWidth` | [#](https://reactnative.dev/docs/layout-props#maxwidth)
|
||
`minHeight` | [#](https://reactnative.dev/docs/layout-props#minheight)
|
||
`minWidth` | [#](https://reactnative.dev/docs/layout-props#minwidth)
|
||
`overflow` | [#](https://reactnative.dev/docs/layout-props#overflow)
|
||
`padding` | [#](https://reactnative.dev/docs/layout-props#padding)
|
||
`paddingBottom` | [#](https://reactnative.dev/docs/layout-props#paddingbottom)
|
||
`paddingEnd` | [#](https://reactnative.dev/docs/layout-props#paddingend)
|
||
`paddingHorizontal` | [#](https://reactnative.dev/docs/layout-props#paddinghorizontal)
|
||
`paddingLeft` | [#](https://reactnative.dev/docs/layout-props#paddingleft)
|
||
`paddingRight` | [#](https://reactnative.dev/docs/layout-props#paddingright)
|
||
`paddingStart` | [#](https://reactnative.dev/docs/layout-props#paddingstart)
|
||
`paddingTop` | [#](https://reactnative.dev/docs/layout-props#paddingtop)
|
||
`paddingVertical` | [#](https://reactnative.dev/docs/layout-props#paddingvertical)
|
||
`position` | [#](https://reactnative.dev/docs/layout-props#position)
|
||
`right` | [#](https://reactnative.dev/docs/layout-props#right)
|
||
`start` | [#](https://reactnative.dev/docs/layout-props#start)
|
||
`top` | [#](https://reactnative.dev/docs/layout-props#top)
|
||
`width` | [#](https://reactnative.dev/docs/layout-props#width)
|
||
`zIndex` | [#](https://reactnative.dev/docs/layout-props#zindex)
|
||
|
||
### Image Style Props
|
||
|
||
```jsx
|
||
<Image
|
||
style={{
|
||
resizeMode: "contain",
|
||
height: 100,
|
||
width: 200
|
||
}}
|
||
source={require("@expo/snack-static/react-native-logo.png")}
|
||
/>
|
||
```
|
||
<!--rehype:className=wrap-text-->
|
||
|
||
---
|
||
|
||
:- | --
|
||
:- | --
|
||
`backfaceVisibility` | [#](https://reactnative.dev/docs/image-style-props#backfacevisibility)
|
||
`backgroundColor` | [#](https://reactnative.dev/docs/image-style-props#backgroundcolor)
|
||
`borderBottomLeftRadius` | [#](https://reactnative.dev/docs/image-style-props#borderbottomleftradius)
|
||
`borderBottomRightRadius` | [#](https://reactnative.dev/docs/image-style-props#borderbottomrightradius)
|
||
`borderColor` | [#](https://reactnative.dev/docs/image-style-props#bordercolor)
|
||
`borderRadius` | [#](https://reactnative.dev/docs/image-style-props#borderradius)
|
||
`borderTopLeftRadius` | [#](https://reactnative.dev/docs/image-style-props#bordertopleftradius)
|
||
`borderTopRightRadius` | [#](https://reactnative.dev/docs/image-style-props#bordertoprightradius)
|
||
`borderWidth` | [#](https://reactnative.dev/docs/image-style-props#borderwidth)
|
||
`opacity` | [#](https://reactnative.dev/docs/image-style-props#opacity)
|
||
`overflow` | [#](https://reactnative.dev/docs/image-style-props#overflow)
|
||
`overlayColor` | [#](https://reactnative.dev/docs/image-style-props#overlaycolor-android)
|
||
`resizeMode` | [#](https://reactnative.dev/docs/image-style-props#resizemode)
|
||
`tintColor` | [#](https://reactnative.dev/docs/image-style-props#tintcolor)
|