t1k:rn:base:platform-specific
| Field | Value |
|---|---|
| Module | base |
| Version | 1.7.4 |
| Effort | medium |
| Tools | — |
Keywords: android, ios, native bridge, platform, Platform.select, react native
How to invoke
Section titled “How to invoke”/t1k:rn:base:platform-specificRN Base Platform-Specific
Section titled “RN Base Platform-Specific”Platform.select Pattern
Section titled “Platform.select Pattern”import { Platform, StyleSheet } from 'react-native';
const styles = StyleSheet.create({ shadow: Platform.select({ ios: { shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.25, shadowRadius: 4, }, android: { elevation: 4, }, }),});
// Conditional renderingconst StatusBarHeight = Platform.OS === 'ios' ? 44 : 24;Platform File Extensions
Section titled “Platform File Extensions”components/├── HapticTab.tsx # shared logic├── HapticTab.ios.tsx # iOS override (auto-resolved)└── HapticTab.android.tsx # Android override (auto-resolved)Metro resolves .ios.tsx → .android.tsx → .tsx automatically. No import changes needed.
Native Module Bridging (Legacy Architecture)
Section titled “Native Module Bridging (Legacy Architecture)”import { NativeModules, Platform } from 'react-native';
const { HapticsModule } = NativeModules;
export const triggerHaptic = (type: 'light' | 'medium' | 'heavy') => { if (Platform.OS === 'ios') { HapticsModule?.trigger(type); }};Expo Modules API (Preferred for new native code)
Section titled “Expo Modules API (Preferred for new native code)”// Use expo-modules-core for new native modulesimport MyModule from './MyModuleModule';export { MyModule };Safe Area Handling
Section titled “Safe Area Handling”import { useSafeAreaInsets } from 'react-native-safe-area-context';
export function Screen({ children }: { children: React.ReactNode }) { const insets = useSafeAreaInsets(); return ( <View style={{ flex: 1, paddingTop: insets.top, paddingBottom: insets.bottom }}> {children} </View> );}Key Rules
Section titled “Key Rules”- Never hardcode status bar heights — use
useSafeAreaInsets() - Use platform extensions for substantial platform differences,
Platform.selectfor style-only - Expo Modules API > Legacy NativeModules for new native code
- Test on both iOS simulator AND Android emulator — behavior often differs
Gotchas
Section titled “Gotchas”Platform.selectreturnsundefinedif platform not listed — always providedefaultkey- Platform extensions work in Metro but NOT in Jest — mock with
jest.mockor__mocks__ elevation(Android) andshadow*(iOS) are separate systems — both needed for cross-platform shadowSafeAreaProvidermust wrap the entire app at root level — not per-screen