ReactNative 核心组件
组件概览
React Native 中的组件编译为原生 UI,所有组件需从 react-native 导入:
tsx
import { View, Text, Image } from 'react-native'import { View, Text, Image } from 'react-native'View
最基础的容器组件,类似 HTML 的 div:
tsx
<View style={styles.container}>
<Text>Content</Text>
</View><View style={styles.container}>
<Text>Content</Text>
</View>- 支持 Flexbox 布局
- 支持触摸事件(onStartShouldSetResponder 等)
- 默认不显示任何内容(需设置背景色等样式)
Text
文本显示组件,字符串必须放在 Text 组件内:
tsx
<Text style={{ fontSize: 16, color: '#333' }}>
你好,世界
</Text>
// 嵌套 Text
<Text>
这是 <Text style={{ fontWeight: 'bold' }}>加粗</Text> 文本
</Text>
// 显示行数限制
<Text numberOfLines={2}>超出 2 行显示省略号</Text><Text style={{ fontSize: 16, color: '#333' }}>
你好,世界
</Text>
// 嵌套 Text
<Text>
这是 <Text style={{ fontWeight: 'bold' }}>加粗</Text> 文本
</Text>
// 显示行数限制
<Text numberOfLines={2}>超出 2 行显示省略号</Text>注意事项:
- 字符串不能直接放在 View 中
- 文字样式(fontSize、color 等)必须在 Text 上设置
Image
本地图片
tsx
<Image source={require('./assets/avatar.png')} style={styles.image} /><Image source={require('./assets/avatar.png')} style={styles.image} />网络图片
tsx
<Image
source={{ uri: 'https://example.com/photo.jpg' }}
style={{ width: 200, height: 200 }}
/><Image
source={{ uri: 'https://example.com/photo.jpg' }}
style={{ width: 200, height: 200 }}
/>注意:网络图片必须指定宽高。本地图片会自动获取尺寸。
ImageBackground
背景图容器,类似 HTML 的 background-image:
tsx
<ImageBackground source={require('./assets/bg.png')} style={styles.background}>
<Text>在背景上的内容</Text>
</ImageBackground><ImageBackground source={require('./assets/bg.png')} style={styles.background}>
<Text>在背景上的内容</Text>
</ImageBackground>ScrollView
可滚动容器,内容超出屏幕宽度时需要 ScrollView:
tsx
<ScrollView
horizontal={false} // 是否水平滚动
showsVerticalScrollIndicator={true}
onScroll={handleScroll}
>
<Text>内容多长,滚动区域就多高</Text>
</ScrollView><ScrollView
horizontal={false} // 是否水平滚动
showsVerticalScrollIndicator={true}
onScroll={handleScroll}
>
<Text>内容多长,滚动区域就多高</Text>
</ScrollView>- 所有内容会一次性渲染,不适合长列表
- 长列表应使用 FlatList
FlatList
虚拟列表,只渲染当前可见项,适合长列表:
tsx
const data = [
{ id: '1', title: 'Item 1' },
{ id: '2', title: 'Item 2' },
]
<FlatList
data={data}
keyExtractor={item => item.id}
renderItem={({ item }) => <Text>{item.title}</Text>}
refreshing={refreshing}
onRefresh={handleRefresh}
onEndReached={loadMore}
ListEmptyComponent={<Text>暂无数据</Text>}
/>const data = [
{ id: '1', title: 'Item 1' },
{ id: '2', title: 'Item 2' },
]
<FlatList
data={data}
keyExtractor={item => item.id}
renderItem={({ item }) => <Text>{item.title}</Text>}
refreshing={refreshing}
onRefresh={handleRefresh}
onEndReached={loadMore}
ListEmptyComponent={<Text>暂无数据</Text>}
/>常用属性:
| 属性 | 说明 |
|---|---|
data | 数据源 |
renderItem | 每项的渲染函数 |
keyExtractor | 唯一 key |
refreshing / onRefresh | 下拉刷新 |
onEndReached | 触底加载更多 |
ListHeaderComponent | 列表头部 |
ListFooterComponent | 列表尾部 |
ListEmptyComponent | 空状态 |
numColumns | 多列布局 |
initialNumToRender | 初始渲染条数 |
SectionList
分组列表,类似 iOS 的 UITableView(sectioned):
tsx
const sections = [
{ title: '水果', data: ['苹果', '香蕉'] },
{ title: '蔬菜', data: ['白菜', '萝卜'] },
]
<SectionList
sections={sections}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => <Text>{item}</Text>}
renderSectionHeader={({ section }) => (
<Text style={{ fontWeight: 'bold' }}>{section.title}</Text>
)}
/>const sections = [
{ title: '水果', data: ['苹果', '香蕉'] },
{ title: '蔬菜', data: ['白菜', '萝卜'] },
]
<SectionList
sections={sections}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => <Text>{item}</Text>}
renderSectionHeader={({ section }) => (
<Text style={{ fontWeight: 'bold' }}>{section.title}</Text>
)}
/>TextInput
文本输入框:
tsx
const [value, setValue] = useState('')
<TextInput
style={styles.input}
value={value}
onChangeText={setValue}
placeholder="请输入..."
secureTextEntry={false} // 密码模式
keyboardType="default" // default / numeric / email-address / phone-pad
multiline={false}
maxLength={100}
returnKeyType="done" // 键盘回车键类型
/>const [value, setValue] = useState('')
<TextInput
style={styles.input}
value={value}
onChangeText={setValue}
placeholder="请输入..."
secureTextEntry={false} // 密码模式
keyboardType="default" // default / numeric / email-address / phone-pad
multiline={false}
maxLength={100}
returnKeyType="done" // 键盘回车键类型
/>TouchableOpacity / TouchableHighlight
触摸响应组件,用于点击事件:
tsx
// 点击透明度变化
<TouchableOpacity onPress={() => alert('点击')} activeOpacity={0.7}>
<Text>按钮</Text>
</TouchableOpacity>
// 点击高亮
<TouchableHighlight onPress={() => {}} underlayColor="#ddd">
<Text>按钮</Text>
</TouchableHighlight>// 点击透明度变化
<TouchableOpacity onPress={() => alert('点击')} activeOpacity={0.7}>
<Text>按钮</Text>
</TouchableOpacity>
// 点击高亮
<TouchableHighlight onPress={() => {}} underlayColor="#ddd">
<Text>按钮</Text>
</TouchableHighlight>Pressable
更灵活的触摸组件(React Native 66+),支持更多状态:
tsx
<Pressable
onPress={() => {}}
onPressIn={() => {}} // 按下瞬间
onPressOut={() => {}} // 抬起瞬间
onLongPress={() => {}}
style={({ pressed }) => [
{ backgroundColor: pressed ? '#ddd' : '#fff' }
]}
>
<Text>Pressable 按钮</Text>
</Pressable><Pressable
onPress={() => {}}
onPressIn={() => {}} // 按下瞬间
onPressOut={() => {}} // 抬起瞬间
onLongPress={() => {}}
style={({ pressed }) => [
{ backgroundColor: pressed ? '#ddd' : '#fff' }
]}
>
<Text>Pressable 按钮</Text>
</Pressable>Modal
模态框:
tsx
const [visible, setVisible] = useState(false)
<Modal
animationType="slide" // slide / fade / none
transparent={false}
visible={visible}
onRequestClose={() => setVisible(false)}
>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>模态内容</Text>
<TouchableOpacity onPress={() => setVisible(false)}>
<Text>关闭</Text>
</TouchableOpacity>
</View>
</Modal>const [visible, setVisible] = useState(false)
<Modal
animationType="slide" // slide / fade / none
transparent={false}
visible={visible}
onRequestClose={() => setVisible(false)}
>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>模态内容</Text>
<TouchableOpacity onPress={() => setVisible(false)}>
<Text>关闭</Text>
</TouchableOpacity>
</View>
</Modal>SafeAreaView
适配刘海屏/挖孔屏的安全区域:
tsx
import { SafeAreaView } from 'react-native'
<SafeAreaView style={{ flex: 1 }}>
{/* 内容会在安全区域内 */}
</SafeAreaView>import { SafeAreaView } from 'react-native'
<SafeAreaView style={{ flex: 1 }}>
{/* 内容会在安全区域内 */}
</SafeAreaView>StatusBar
状态栏配置:
tsx
<StatusBar
barStyle="dark-content" // dark-content / light-content
backgroundColor="#fff"
translucent={false}
/><StatusBar
barStyle="dark-content" // dark-content / light-content
backgroundColor="#fff"
translucent={false}
/>StyleSheet
样式管理:
tsx
const styles = StyleSheet.create({
container: {
flex: 1,
paddingHorizontal: 16,
paddingVertical: 8,
},
title: {
fontSize: 18,
fontWeight: '600',
color: '#333',
},
})
// 多组样式合并
<View style={[styles.container, styles.highlight]} />const styles = StyleSheet.create({
container: {
flex: 1,
paddingHorizontal: 16,
paddingVertical: 8,
},
title: {
fontSize: 18,
fontWeight: '600',
color: '#333',
},
})
// 多组样式合并
<View style={[styles.container, styles.highlight]} />注意:
- 属性使用驼峰命名(
backgroundColor而非background-color) - 不需要 px 单位
- 默认 flex 方向为 column(不同于 Web 的 row)
Flexbox 布局
React Native 默认启用 Flexbox,默认方向为 column:
tsx
// 默认占满剩余空间
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
{/* 居中内容 */}
</View>// 默认占满剩余空间
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
{/* 居中内容 */}
</View>注意:给子元素设置 flex 时,父元素必须有确定高度或 flex:1。
屏幕适配
Dimensions
tsx
import { Dimensions } from 'react-native'
const { width, height } = Dimensions.get('window')
// 设计稿适配
const scale = width / 375import { Dimensions } from 'react-native'
const { width, height } = Dimensions.get('window')
// 设计稿适配
const scale = width / 375Platform
tsx
import { Platform } from 'react-native'
const isIOS = Platform.OS === 'ios'
const isAndroid = Platform.OS === 'android'
// 平台特定样式
const styles = StyleSheet.create({
container: {
...Platform.select({
ios: { shadowColor: '#000' },
android: { elevation: 3 },
}),
},
})import { Platform } from 'react-native'
const isIOS = Platform.OS === 'ios'
const isAndroid = Platform.OS === 'android'
// 平台特定样式
const styles = StyleSheet.create({
container: {
...Platform.select({
ios: { shadowColor: '#000' },
android: { elevation: 3 },
}),
},
})PixelRatio
tsx
import { PixelRatio } from 'react-native'
const pixel = PixelRatio.get() // 设备像素比
const fontScale = PixelRatio.getFontScale() // 字体缩放import { PixelRatio } from 'react-native'
const pixel = PixelRatio.get() // 设备像素比
const fontScale = PixelRatio.getFontScale() // 字体缩放
Cao Note