Skip to main content

Command Palette

Search for a command to run...

The Building Blocks of Mobile

Published
5 min read
O

Hi, I'm Olamiji. I’m a Software Engineer who believes that while code is our tool, life is our canvas. I document my journey through front-end development and the lessons I learn outside the IDE.

In my previous posts, we focused on the "Where" (the environment). Now, let’s talk about the "What." According to the official documentation, React Native is an open-source framework for building apps using React and the platform’s Native capabilities.

What is a "Native Component"?

When you write in JavaScript, React Native invokes the actual views used in Android (Kotlin/Java) or iOS (Swift). At runtime, it creates the corresponding native elements. This is why your app doesn't just look like a real app, it is a real app.

The "Core" vs. HTML

The documentation provides a great "Web Analog" table that helped me instantly understand the transition from Web to Mobile:

React Native ComponentWeb AnalogDescription
<Pressable><button>For handling taps and touches.
<FlatList><ul> / <li>For rendering lists efficiently.
<View><div>A container that supports layout with flexbox and style.
<Text><p> <span>Displays, styles, and nests strings of text.
<Image><img>Displays different types of images.
<ScrollView><div>A generic scrolling container for multiple components.

1. View (The "Div" of Mobile)

The <View> is your universal container.

  • Web Equivalent: <div>.

  • Purpose: It supports layout with Flexbox, styling, and touch handling.

  • Key Rule: Unlike the web, you cannot put raw text directly inside a <View>; it must be wrapped in a <Text> component.

2. Text (The "P" or "Span")

In mobile development, all strings of text must be wrapped in this component.

  • Web Equivalent: <p>, <span>, or <h1>.

  • Feature: It handles styling, nesting, and even touch events.

3. Image

This component is used to display various types of images (network, static, or local).

  • Web Equivalent: <img>.

  • Note: For network images, you must specify a width and height in the style props, or they won't appear on the screen!.

4. ScrollView vs. FlatList

On the web, your page scrolls by default. On mobile, it doesn't.

  • ScrollView: A generic scrolling container that renders all its children at once. Best for small amounts of content.

  • FlatList: A high-performance tool for long lists. It only renders the items currently visible on the screen to save memory (similar to the "FlashList" we discussed in the Pro Stack).

Since we are sticking to the Level 1 (Safe Stack), we will use standard React Native components styled with NativeWind. This is the best way to show how web skills (Tailwind) translate to mobile building blocks.

Styling: The Flexbox "Flip"

This is where we beginners often get tripped up. React Native uses Flexbox for layout, but there is one major difference from the web:

  • Web Default: flex-direction: row.

  • Mobile Default: flex-direction: column.

In your mobile app, elements stack vertically by default. If you want them side-by-side, you must explicitly tell the code to use flex-row.

The "Essential Four" Profile Card

Using the Essential Four core components we just learned, we can build a professional-looking Profile Card. It uses standard React Native components styled with NativeWind (Tailwind CSS) to keep our "Safe Stack" light and fast.

This snippet uses the four building blocks every beginner needs: View, Text, Image, and Pressable.

  • The Flexbox Flip: Notice we didn't define flex-col. In React Native, the View already stacks the Image, Text, and Pressable vertically by default.

  • The Image Rule: For network images (like the avatar URL above), the app won't know the size unless you define it in the className (w-24 h-24).

  • Interaction: We use onPress instead of onClick. Mobile devices don't have "clicks"; they have "presses."

  • Active States: The active:bg-blue-700 class is a NativeWind feature that mimics the "dimming" effect users expect when they touch a button on a phone.

The "Output”

What we expected to see

  • Gray background (bg-gray-100)
  • White card with rounded corners (rounded-3xl), shadow (shadow-lg), and padding
  • Profile image: circular (rounded-full), 96x96px (w-24 h-24), light blue background
  • Text: Name: large (text-2xl), bold (font-bold), dark gray (text-gray-800)
  • Description: medium gray (text-gray-500), centered (text-center), bottom margin (mb-6)
  • Blue button: blue background (bg-blue-600), white text (text-white), rounded (rounded-full), padding, darker on press (active:bg-blue-700)
  • Proper spacing and layout: centered, justified, with gaps

What we actually saw

  • Plain, unstyled black text on a light gray background
  • No card styling (no white background, rounded corners, or shadow)
  • No image visible or styled
  • No button styling (no background color, padding, or rounded corners)
  • No spacing, margins, or layout alignment
  • Plain text with no font weights or sizes
  • Default React Native styling only

Root causes

  1. Babel configuration: nativewind/babel was placed in plugins instead of presets, preventing className transformation

  2. Missing native rebuild: NativeWind v4 requires a full native rebuild after config changes; clearing Metro cache isn't enough

  3. Image format: SVG URL used instead of PNG (React Native Image doesn't support SVG)

Solution

  1. Fixed babel.config.js: moved nativewind/babel to the presets array

  2. Rebuilt the native app: ran npx expo run:ios to apply the Babel configuration changes

  3. Fixed image URL: changed from .svg to .png format

Before vs after

  • Before: Unstyled, plain text, no visual hierarchy, default React Native appearance
  • After: Fully styled with Tailwind classes, proper layout, colors, spacing, and visual design

Now that we have our environment set up and our first component built, we are ready to scale. One card is great, but what if we have a hundred?

In the next part of this series, we will look at Layouts and Lists. You can find the full series here.

More from this blog