Build screens from semantic, typed components rather than styling raw primitives independently in every route. React Native uses native layout and text rules, so web CSS habits do not always transfer.
Pick the Correct Primitive
Viewgroups and lays out content.Textowns text styling and inline text nesting.Pressablehandles custom interaction states; give it an accessibility role and label where needed.TextInputowns editable text, keyboard configuration, and focus.Imagerenders bundled or remote images; remote images need explicit dimensions or aspect ratio.ScrollViewis for bounded content;FlatListis for long or dynamic collections.
Avoid nesting a virtualized list inside a same-direction ScrollView. Give list items stable keys and keep renderItem free of avoidable allocations when measurement shows list pressure.
Use Flexbox Deliberately
React Native defaults to a vertical flex direction. Set flexDirection: "row" only when the visual relationship is horizontal.
justifyContentdistributes along the main axis.alignItemsaligns across the cross axis.flexdistributes available space; it does not mean a fixed percentage.gapexpresses spacing between siblings when supported by the target RN version.- Absolute positioning is for overlays and anchored decoration, not the main screen layout.
Test narrow phones, large text, long translations, and the keyboard. A layout that only works at one simulator size is unfinished.
Treat StyleSheet as a Boundary
Use StyleSheet.create for stable styles, StyleSheet.compose to combine variants, StyleSheet.flatten only when a concrete object is required, StyleSheet.hairlineWidth for device-appropriate separators, and StyleSheet.absoluteFillObject for overlays.
Prefer arrays for conditional styles:
<View style={[styles.card, selected && styles.selected, style]} />
Keep the caller's style last when intentional overrides are part of the component contract. Do not accept overrides that can break required layout or accessibility without documenting that freedom.
Design Reusable Components as APIs
Expose meaning, not internal colors or padding:
type ButtonProps = {
label: string;
variant?: "primary" | "secondary" | "destructive";
size?: "compact" | "regular";
loading?: boolean;
disabled?: boolean;
onPress: () => void;
};
Resolve variants through a finite map. Keep disabled and loading behavior consistent, prevent duplicate submission, preserve the button's dimensions while loading, and expose state to accessibility APIs.
Translate Designs into Rules
From Figma, extract recurring tokens and component states rather than copying coordinates. Record spacing, typography, radii, colors, icons, interaction states, and responsive rules. Ask what changes with platform, width, content, and text size before implementing the static frame.
Sources
Check implementation details against the React Native documentation for core components, Flexbox, StyleSheet, images, and using TypeScript.