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

14. Platform-specific код

React Native запускается на iOS и Android. Некоторые вещи работают по-разному, и нужно учитывать платформу.

import { Platform } from 'react-native';
console.log(Platform.OS); // 'ios' | 'android' | 'web'
console.log(Platform.Version); // '17.0' (iOS) | 33 (Android API level)
if (Platform.OS === 'ios') {
// iOS-специфичный код
}
import { Platform, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
header: {
paddingTop: Platform.select({ ios: 44, android: 24, default: 0 }),
...Platform.select({
ios: {
shadowColor: '#000',
shadowOpacity: 0.2,
shadowRadius: 4,
},
android: { elevation: 4 },
}),
},
font: {
fontFamily: Platform.select({ ios: 'SF Pro Display', android: 'Roboto' }),
},
});

React Native автоматически выбирает нужный файл:

Button.ios.tsx → на iOS
Button.android.tsx → на Android
Button.tsx → fallback
Button.ios.tsx
import * as Haptics from 'expo-haptics';
export function Button({ onPress, title }) {
const handlePress = () => {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
onPress();
};
return <Pressable onPress={handlePress}><Text>{title}</Text></Pressable>;
}
// Button.android.tsx — ripple эффект
export function Button({ onPress, title }) {
return (
<Pressable android_ripple={{ color: 'rgba(203,166,247,0.3)' }} onPress={onPress}>
<Text>{title}</Text>
</Pressable>
);
}
import { StatusBar } from 'expo-status-bar';
<StatusBar style="light" backgroundColor="#1e1e2e" />

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

import { SafeAreaView } from 'react-native-safe-area-context';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
// Hook для ручного управления
function Screen() {
const insets = useSafeAreaInsets();
return (
<View style={{ paddingTop: insets.top, paddingBottom: insets.bottom }}>
{/* Контент безопасно не перекроется нотчем */}
</View>
);
}
const shadowStyle = Platform.select({
ios: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 8,
},
android: { elevation: 8 },
});