React Native Core Components: Architecture, Styling, and Custom Component Patterns

In React Native development, components serve as the fundamental building blocks of mobile interfaces. Unlike web development where HTML tags like <div>, <span>, and <button> render in a browser DOM, React Native maps JavaScript components directly to native UI primitives on iOS (such as UIView and UILabel) and Android (such as android.view.View and TextView).

In this guide, we will explore the core React Native component primitives, layout patterns with Flexbox, touch handling with Pressable, custom component abstraction, and architectural best practices for cross-platform apps.


1. The Core Primitives: View, Text, and Image

Every React Native layout is constructed from a small set of primary components provided directly by the framework framework.

  • View: The most fundamental container component. It maps directly to native view representations on iOS and Android and supports layout via Flexbox, style properties, touch response, and accessibility controls.
  • Text: In React Native, text strings must be wrapped inside a <Text> component. Plain raw text rendered inside a View will throw a runtime error. Text components support nesting, styling inheritance within nested text elements, and touch handling.
  • Image & ImageBackground: Used to render static images, network resources, or local assets. Network images require an explicit width and height in their style object because size cannot be inferred prior to download.

Core Primitives Example

import React from 'react';
import { View, Text, Image, StyleSheet } from 'react-native';

export function UserAvatarCard() {
  return (
    <View style={styles.cardContainer}>
      <Image
        source={{ uri: 'https://via.placeholder.com/100' }}
        style={styles.avatar}
      />
      <View style={styles.textContainer}>
        <Text style={styles.userName}>Alex Morgan</Text>
        <Text style={styles.userRole}>Senior Mobile Engineer</Text>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  cardContainer: {
    flexDirection: 'row',
    padding: 16,
    backgroundColor: '#ffffff',
    borderRadius: 12,
    alignItems: 'center',
    shadowColor: '#000',
    shadowOpacity: 0.1,
    shadowRadius: 6,
    elevation: 3, // Android shadow
  },
  avatar: {
    width: 60,
    height: 60,
    borderRadius: 30,
  },
  textContainer: {
    marginLeft: 16,
  },
  userName: {
    fontSize: 18,
    fontWeight: 'bold',
    color: '#0f172a',
  },
  userRole: {
    fontSize: 14,
    color: '#64748b',
    marginTop: 2,
  },
});

2. User Interaction: Replacing Legacy Touchables with `Pressable`

In older React Native codebases, touch interactions were handled using TouchableOpacity, TouchableHighlight, or TouchableWithoutFeedback. While still supported, the modern standard is the Pressable API.

Pressable provides a single, unified interface that detects various stages of press interactions (press in, press out, long press) and allows dynamic style functions based on the current press state.

Modern Button Component with Pressable

import React from 'react';
import { Pressable, Text, StyleSheet } from 'react-native';

interface CustomButtonProps {
  onPress: () => void;
  title: string;
  variant?: 'primary' | 'secondary';
}

export function CustomButton({ onPress, title, variant = 'primary' }: CustomButtonProps) {
  return (
    <Pressable
      onPress={onPress}
      style={({ pressed }) => [
        styles.button,
        variant === 'secondary' ? styles.secondary : styles.primary,
        pressed && styles.pressedState,
      ]}
    >
      <Text style={[styles.text, variant === 'secondary' && styles.secondaryText]}>
        {title}
      </Text>
    </Pressable>
  );
}

const styles = StyleSheet.create({
  button: {
    paddingVertical: 12,
    paddingHorizontal: 24,
    borderRadius: 8,
    alignItems: 'center',
    justifyContent: 'center',
  },
  primary: {
    backgroundColor: '#3b82f6',
  },
  secondary: {
    backgroundColor: 'transparent',
    borderWidth: 1,
    borderColor: '#3b82f6',
  },
  pressedState: {
    opacity: 0.7,
    transform: [{ scale: 0.98 }],
  },
  text: {
    color: '#ffffff',
    fontSize: 16,
    fontWeight: '600',
  },
  secondaryText: {
    color: '#3b82f6',
  },
});

3. Flexbox Layout Engine in React Native

React Native uses a custom layout engine (Yoga) that implements the CSS Flexbox specification. However, there are two crucial differences compared to CSS on the web:

  1. Default Direction: flexDirection defaults to column (vertical) in React Native, whereas on the web it defaults to row (horizontal).
  2. Flex Dimensions: The flex property takes a single number (e.g., flex: 1), which defines the component's ability to grow or shrink relative to sibling elements within the parent container.

4. Overview Matrix: React Native Core Components

Component Web Equivalent Primary Usage Key Property / Consideration
View <div> / <section> Container, layout structuring Supports Flexbox; defaults to flexDirection: 'column'
Text <p> / <span> Displaying typography All text nodes must be wrapped inside this component
Image <img> Rendering raster & vector images Remote URIs require explicit width and height styles
Pressable <button> Handling user gestures & taps Modern replacement for legacy TouchableOpacity
TextInput <input> / <textarea> Capturing keyboard input Requires state control via onChangeText
SafeAreaView N/A Avoiding camera notches & home indicators Renders content within hardware boundaries (iOS/Android)

5. Component Architecture Best Practices

When building production mobile applications, follow these component composition rules:

  • Decouple Styles using StyleSheet.create: Avoid inline object creation (e.g., style={{ padding: 20 }}) in render loops. Using StyleSheet.create ensures style IDs are allocated once natively, reducing garbage collection pressure.
  • Build Small Atomic Components: Extract complex screens into isolated visual primitives (Buttons, Inputs, Cards, Badges) to ensure consistent UI across screens and make unit testing easier.
  • Use Safe Areas: Wrap top-level screen containers in SafeAreaView (or useSafeAreaInsets from react-native-safe-area-context) to prevent hardware UI overlap on notch and punch-hole displays.

Conclusion

Mastering React Native components starts with understanding how primitives like View, Text, and Pressable translate to native layout engines. By organizing custom re-usable components, utilizing Flexbox effectively, and adhering to native performance standards, you can build seamless, production-grade mobile interfaces for iOS and Android.

Happy Mobile Engineering! 🚀

Comments

Popular posts from this blog

React Performance Optimization: Profiling, Reconciliation, and Rendering Boundaries

Mastering React Icons: Installation, Customization, and Best Practices (2026 Guide)

How to Configure Webpack 5 with React from Scratch (2026 Guide)