ReactNative组件技能Skill react-native-components

这个技能专注于使用 React Native 构建移动应用的用户界面组件,包括核心组件如 View、Text、Image,以及自定义组件和常见模式。适用于移动开发、前端开发,关键词包括 React Native、UI 组件、移动应用开发、组件库、前端技术。

移动开发 0 次安装 0 次浏览 更新于 3/25/2026

名称: react-native-components 用户可调用: 否 描述: 当构建 React Native UI 组件时使用,包括核心组件、自定义组件和组件模式。涵盖 View、Text、Image、ScrollView、FlatList 和组件组合。 允许工具:

  • 读取
  • 写入
  • 编辑
  • Bash
  • Grep
  • Glob

React Native 组件

使用此技能在使用 React Native 的核心组件构建用户界面和创建自定义可重用组件时。

核心概念

核心组件

React Native 提供平台无关的组件,映射到原生视图:

import React from 'react';
import {
  View,
  Text,
  Image,
  ScrollView,
  TextInput,
  TouchableOpacity,
  SafeAreaView,
} from 'react-native';

export default function App() {
  return (
    <SafeAreaView style={{ flex: 1 }}>
      <ScrollView>
        <View>
          <Text>你好, React Native!</Text>
          <Image
            source={{ uri: 'https://example.com/image.jpg' }}
            style={{ width: 200, height: 200 }}
          />
          <TextInput
            placeholder="输入文本"
            style={{ borderWidth: 1, padding: 10 }}
          />
          <TouchableOpacity onPress={() => console.log('按下')}>
            <Text>按下我</Text>
          </TouchableOpacity>
        </View>
      </ScrollView>
    </SafeAreaView>
  );
}

View 组件

基础构建块:

import { View } from 'react-native';

function Container({ children }: { children: React.ReactNode }) {
  return (
    <View style={{
      flex: 1,
      padding: 16,
      backgroundColor: '#fff',
    }}>
      {children}
    </View>
  );
}

Text 组件

所有文本必须包裹在 <Text> 中:

import { Text } from 'react-native';

function Heading({ children }: { children: string }) {
  return (
    <Text style={{
      fontSize: 24,
      fontWeight: 'bold',
      color: '#333',
    }}>
      {children}
    </Text>
  );
}

function Body({ children }: { children: string }) {
  return (
    <Text style={{
      fontSize: 16,
      lineHeight: 24,
      color: '#666',
    }}>
      {children}
    </Text>
  );
}

Image 组件

显示来自不同源的图像:

import { Image } from 'react-native';

// 远程图像
<Image
  source={{ uri: 'https://example.com/image.jpg' }}
  style={{ width: 200, height: 200 }}
/>

// 本地图像
<Image
  source={require('./assets/logo.png')}
  style={{ width: 100, height: 100 }}
/>

// 带有调整大小模式
<Image
  source={{ uri: 'https://example.com/image.jpg' }}
  style={{ width: 200, height: 200 }}
  resizeMode="cover"
/>

最佳实践

使用 SafeAreaView 处理 iOS 刘海

始终使用 SafeAreaView 处理安全区域:

import { SafeAreaView } from 'react-native';

export default function App() {
  return (
    <SafeAreaView style={{ flex: 1, backgroundColor: '#fff' }}>
      {/* 你的内容 */}
    </SafeAreaView>
  );
}

对长列表使用 FlatList

使用 FlatList 替代 ScrollView 以提高性能:

import { FlatList, Text, View } from 'react-native';

interface Item {
  id: string;
  title: string;
}

function ItemList({ items }: { items: Item[] }) {
  return (
    <FlatList
      data={items}
      keyExtractor={(item) => item.id}
      renderItem={({ item }) => (
        <View style={{ padding: 16 }}>
          <Text>{item.title}</Text>
        </View>
      )}
      // 性能优化
      removeClippedSubviews={true}
      maxToRenderPerBatch={10}
      updateCellsBatchingPeriod={50}
      initialNumToRender={10}
      windowSize={10}
    />
  );
}

可触摸组件

为平台使用适当的可触摸组件:

import { TouchableOpacity, TouchableHighlight, Pressable } from 'react-native';

// 现代方法 - Pressable(推荐)
<Pressable
  onPress={() => console.log('按下')}
  style={({ pressed }) => [
    { padding: 12, backgroundColor: pressed ? '#ddd' : '#fff' }
  ]}
>
  {({ pressed }) => (
    <Text style={{ color: pressed ? '#000' : '#333' }}>按下我</Text>
  )}
</Pressable>

// TouchableOpacity - 简单淡入效果
<TouchableOpacity
  onPress={() => console.log('按下')}
  activeOpacity={0.7}
>
  <Text>按下我</Text>
</TouchableOpacity>

组件组合

从简单组件构建复杂 UI:

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

interface CardProps {
  title: string;
  subtitle?: string;
  children?: React.ReactNode;
}

function Card({ title, subtitle, children }: CardProps) {
  return (
    <View style={styles.card}>
      <View style={styles.header}>
        <Text style={styles.title}>{title}</Text>
        {subtitle && <Text style={styles.subtitle}>{subtitle}</Text>}
      </View>
      {children && <View style={styles.content}>{children}</View>}
    </View>
  );
}

const styles = StyleSheet.create({
  card: {
    backgroundColor: '#fff',
    borderRadius: 8,
    padding: 16,
    marginVertical: 8,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
    elevation: 3,
  },
  header: {
    marginBottom: 12,
  },
  title: {
    fontSize: 18,
    fontWeight: 'bold',
    color: '#333',
  },
  subtitle: {
    fontSize: 14,
    color: '#666',
    marginTop: 4,
  },
  content: {
    marginTop: 8,
  },
});

export default Card;

常见模式

带下拉刷新的列表

import React, { useState, useCallback } from 'react';
import { FlatList, RefreshControl, Text, View } from 'react-native';

interface Item {
  id: string;
  title: string;
}

function RefreshableList({ items, onRefresh }: {
  items: Item[];
  onRefresh: () => Promise<void>;
}) {
  const [refreshing, setRefreshing] = useState(false);

  const handleRefresh = useCallback(async () => {
    setRefreshing(true);
    await onRefresh();
    setRefreshing(false);
  }, [onRefresh]);

  return (
    <FlatList
      data={items}
      keyExtractor={(item) => item.id}
      renderItem={({ item }) => (
        <View style={{ padding: 16 }}>
          <Text>{item.title}</Text>
        </View>
      )}
      refreshControl={
        <RefreshControl refreshing={refreshing} onRefresh={handleRefresh} />
      }
    />
  );
}

无限滚动列表

import React from 'react';
import { FlatList, ActivityIndicator, View } from 'react-native';

interface Item {
  id: string;
  title: string;
}

function InfiniteList({
  items,
  loading,
  onEndReached
}: {
  items: Item[];
  loading: boolean;
  onEndReached: () => void;
}) {
  return (
    <FlatList
      data={items}
      keyExtractor={(item) => item.id}
      renderItem={({ item }) => (
        <View style={{ padding: 16 }}>
          <Text>{item.title}</Text>
        </View>
      )}
      onEndReached={onEndReached}
      onEndReachedThreshold={0.5}
      ListFooterComponent={
        loading ? (
          <View style={{ padding: 16 }}>
            <ActivityIndicator size="large" />
          </View>
        ) : null
      }
    />
  );
}

Modal 组件

import React from 'react';
import {
  Modal,
  View,
  Text,
  TouchableOpacity,
  StyleSheet,
} from 'react-native';

interface CustomModalProps {
  visible: boolean;
  title: string;
  children: React.ReactNode;
  onClose: () => void;
}

function CustomModal({ visible, title, children, onClose }: CustomModalProps) {
  return (
    <Modal
      visible={visible}
      animationType="slide"
      transparent={true}
      onRequestClose={onClose}
    >
      <View style={styles.overlay}>
        <View style={styles.modal}>
          <View style={styles.header}>
            <Text style={styles.title}>{title}</Text>
            <TouchableOpacity onPress={onClose}>
              <Text style={styles.closeButton}>✕</Text>
            </TouchableOpacity>
          </View>
          <View style={styles.content}>{children}</View>
        </View>
      </View>
    </Modal>
  );
}

const styles = StyleSheet.create({
  overlay: {
    flex: 1,
    backgroundColor: 'rgba(0, 0, 0, 0.5)',
    justifyContent: 'center',
    alignItems: 'center',
  },
  modal: {
    width: '80%',
    backgroundColor: '#fff',
    borderRadius: 12,
    padding: 20,
  },
  header: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: 16,
  },
  title: {
    fontSize: 20,
    fontWeight: 'bold',
  },
  closeButton: {
    fontSize: 24,
    color: '#666',
  },
  content: {
    marginTop: 8,
  },
});

export default CustomModal;

表单输入组件

import React, { useState } from 'react';
import {
  View,
  TextInput,
  Text,
  StyleSheet,
  TextInputProps,
} from 'react-native';

interface FormInputProps extends TextInputProps {
  label: string;
  error?: string;
}

function FormInput({ label, error, ...props }: FormInputProps) {
  const [isFocused, setIsFocused] = useState(false);

  return (
    <View style={styles.container}>
      <Text style={styles.label}>{label}</Text>
      <TextInput
        {...props}
        style={[
          styles.input,
          isFocused && styles.inputFocused,
          error && styles.inputError,
        ]}
        onFocus={() => setIsFocused(true)}
        onBlur={() => setIsFocused(false)}
      />
      {error && <Text style={styles.error}>{error}</Text>}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    marginVertical: 8,
  },
  label: {
    fontSize: 14,
    fontWeight: '600',
    marginBottom: 4,
    color: '#333',
  },
  input: {
    borderWidth: 1,
    borderColor: '#ddd',
    borderRadius: 8,
    padding: 12,
    fontSize: 16,
  },
  inputFocused: {
    borderColor: '#007AFF',
  },
  inputError: {
    borderColor: '#FF3B30',
  },
  error: {
    color: '#FF3B30',
    fontSize: 12,
    marginTop: 4,
  },
});

export default FormInput;

反模式

不要嵌套 ScrollViews

// 坏 - 嵌套 ScrollViews 导致问题
<ScrollView>
  <ScrollView>
    <Text>内容</Text>
  </ScrollView>
</ScrollView>

// 好 - 使用单个 ScrollView
<ScrollView>
  <View>
    <Text>内容</Text>
  </View>
</ScrollView>

不要对静态值使用内联样式

// 坏 - 每次渲染创建新对象
<View style={{ padding: 16, backgroundColor: '#fff' }}>
  <Text>内容</Text>
</View>

// 好 - 使用 StyleSheet
const styles = StyleSheet.create({
  container: {
    padding: 16,
    backgroundColor: '#fff',
  },
});

<View style={styles.container}>
  <Text>内容</Text>
</View>

不要忘记设置 keyExtractor

// 坏 - 可能导致渲染问题
<FlatList
  data={items}
  renderItem={({ item }) => <Text>{item.title}</Text>}
/>

// 好 - 提供唯一键
<FlatList
  data={items}
  keyExtractor={(item) => item.id}
  renderItem={({ item }) => <Text>{item.title}</Text>}
/>

不要使用索引作为键

// 坏 - 索引作为键会导致重排序问题
<FlatList
  data={items}
  keyExtractor={(item, index) => index.toString()}
  renderItem={({ item }) => <Text>{item.title}</Text>}
/>

// 好 - 使用唯一标识符
<FlatList
  data={items}
  keyExtractor={(item) => item.id}
  renderItem={({ item }) => <Text>{item.title}</Text>}
/>

相关技能

  • react-native-styling: 使用 StyleSheet 样式化组件
  • react-native-navigation: 屏幕间导航
  • react-native-performance: 优化组件性能