Перейти к содержимому

4. Основные компоненты

React Native имеет свои базовые компоненты вместо HTML тегов. Нет div, span, p — только нативные компоненты.

View — это как div в вебе. Используется для группировки и позиционирования.

import { View, StyleSheet } from 'react-native';
// View поддерживает Flexbox, margin, padding, border
export default function App() {
return (
<View style={styles.container}>
<View style={styles.box} />
<View style={styles.box} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
gap: 8,
padding: 16,
},
box: {
width: 50,
height: 50,
backgroundColor: '#cba6f7',
borderRadius: 8,
},
});

Весь текст в React Native должен быть внутри компонента Text.

import { Text, StyleSheet } from 'react-native';
<Text style={styles.title}>Заголовок</Text>
<Text style={styles.body} numberOfLines={2}>
Длинный текст, который будет обрезан после двух строк...
</Text>
<Text>
Обычный текст с <Text style={{ color: 'pink' }}>выделенным</Text> словом
</Text>
import { Image, StyleSheet } from 'react-native';
// Локальный файл
<Image source={require('./assets/logo.png')} style={styles.image} />
// Удалённый URL
<Image
source={{ uri: 'https://example.com/photo.jpg' }}
style={styles.image}
resizeMode="cover" // contain | stretch | repeat | center
/>
// С placeholder и обработкой ошибок
<Image
source={{ uri: imageUrl }}
style={styles.avatar}
defaultSource={require('./assets/placeholder.png')}
onError={() => console.log('Ошибка загрузки')}
/>
import { Button, TouchableOpacity, Pressable, Text } from 'react-native';
// Встроенная кнопка (минимум кастомизации)
<Button title="Нажать" onPress={() => alert('Привет!')} color="#cba6f7" />
// TouchableOpacity — уменьшает opacity при нажатии
<TouchableOpacity
style={styles.button}
onPress={() => {}}
activeOpacity={0.7}
>
<Text style={styles.buttonText}>TouchableOpacity</Text>
</TouchableOpacity>
// Pressable — современный, с ripple эффектом (Android)
<Pressable
style={({ pressed }) => [
styles.button,
pressed && { opacity: 0.8, transform: [{ scale: 0.98 }] }
]}
onPress={() => {}}
onLongPress={() => console.log('Долгое нажатие')}
>
<Text>Pressable</Text>
</Pressable>

Учитывает notch, Dynamic Island, home indicator:

import { SafeAreaView, SafeAreaProvider } from 'react-native-safe-area-context';
// Оберни приложение
export default function App() {
return (
<SafeAreaProvider>
<SafeAreaView style={{ flex: 1 }}>
{/* Контент не уйдёт под notch */}
</SafeAreaView>
</SafeAreaProvider>
);
}
import { ActivityIndicator } from 'react-native';
<ActivityIndicator size="large" color="#cba6f7" />
<ActivityIndicator size="small" color="#a6e3a1" animating={isLoading} />
import { Modal, View, Text, TouchableOpacity } from 'react-native';
function MyModal({ visible, onClose }) {
return (
<Modal
visible={visible}
transparent={true}
animationType="slide" // none | slide | fade
onRequestClose={onClose}
>
<View style={styles.overlay}>
<View style={styles.modal}>
<Text>Контент модала</Text>
<TouchableOpacity onPress={onClose}>
<Text>Закрыть</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
);
}
import { Switch } from 'react-native';
const [enabled, setEnabled] = useState(false);
<Switch
value={enabled}
onValueChange={setEnabled}
trackColor={{ false: '#767577', true: '#a6e3a1' }}
thumbColor={enabled ? '#1e1e2e' : '#f4f3f4'}
/>