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

ComponentRenders asNotes
ViewUIView / android.ViewA flex container; no text allowed inside directly
TextUILabel / TextViewText nests inside Text, and inherits its style
ImageNative image viewNeeds explicit width and height, or resizeMode plus a sized parent
TextInputNative text fieldControlled with value and onChangeText
ScrollViewScroll containerRenders all children; only for short, known lists
FlatListVirtualised listUse for long lists; recycles rows
PressableTouchable wrapperReplaces the older TouchableOpacity
ModalNative modal containerPresented 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. flexDirection defaults to column rather than row.
  • flex: 1 means 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, padding and margin accept numbers; percentage strings are allowed only for width, height and margins.
  • The value undefined in 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.

Setup and your first screen Navigation, native modules and Expo

Last refreshed 2026-09-18.