Core components and styling
The components that map onto native views, and the styling rules that differ from CSS on the web.
The core set
| Component | Renders as | Notes |
|---|---|---|
View | UIView / android.View | A flex container; no text allowed inside directly |
Text | UILabel / TextView | Text nests inside Text, and inherits its style |
Image | Native image view | Needs explicit width and height, or resizeMode plus a sized parent |
TextInput | Native text field | Controlled with value and onChangeText |
ScrollView | Scroll container | Renders all children; only for short, known lists |
FlatList | Virtualised list | Use for long lists; recycles rows |
Pressable | Touchable wrapper | Replaces the older TouchableOpacity |
Modal | Native modal container | Presented above the app; good for short flows |
import { FlatList, Image, Text, View } from 'react-native';
export function NoteList({ notes, onOpen }) {
return (
<FlatList
data={notes}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 12, padding: 12 }}>
<Image source={{ uri: item.avatar }} style={{ width: 44, height: 44, borderRadius: 22 }} />
<Text numberOfLines={1} onPress={() => onOpen(item)} style={{ flex: 1 }}>
{item.title}
</Text>
</View>
)}
ListEmptyComponent={<Text style={{ padding: 24 }}>Nothing here yet.</Text>}
ItemSeparatorComponent={() => <View style={{ height: 1, backgroundColor: '#eee' }} />}
/>
);
}Styling without CSS
Styles are plain JavaScript objects. There are no stylesheets, no cascade and no descendant selectors, so nothing you write in a child affects its parent.
- Flexbox is the default and the only layout engine.
flexDirectiondefaults tocolumnrather thanrow. flex: 1means take the remaining space along the main axis; a child with fixed size inside a flexed parent needs an explicit width or height.- Numbers are density-independent pixels, not CSS pixels. Do not append units.
gap,paddingandmarginaccept numbers; percentage strings are allowed only for width, height and margins.- The value
undefinedin a style object is ignored, which makes conditional styles easy:style={[styles.base, active && styles.active]}.
const card = {
flex: 1,
borderRadius: 12,
padding: 16,
backgroundColor: '#f6f7fb',
shadowColor: '#000',
shadowOpacity: 0.08,
shadowRadius: 6,
shadowOffset: { width: 0, height: 2 },
elevation: 3, // Android uses elevation instead of shadowProps
};
<View style={[card, { marginTop: 12 }]} />⚠️
Shadow properties are iOS-only; Android draws shadows from
elevation and ignores the rest. If a card looks flat on one platform, you set the other platform's property.FAQ
ScrollView or FlatList?
ScrollView renders every child immediately, which is fine for a settings page. For anything backed by an API or longer than a screen or two, use FlatList or SectionList so rows are recycled.Why does my image have zero height?
Image has no intrinsic size in React Native. Give it explicit dimensions, or a parent with a known height plus flex: 1 on the image.Related
Setup and your first screen Navigation, native modules and Expo
Last refreshed 2026-09-18.