Skip to main content
Web MobileIntermediate16 min readUpdated March 2025

Mobile Apps with JavaScript & React Native

Use your JavaScript skills to build native iOS and Android apps. Learn React Native core components, styling, lists and calling a Python API from a phone.

How React Native Works

React Native lets you write components in JavaScript or TypeScript that render real native views instead of a web view. One codebase targets iOS and Android, while you can still drop into native code when needed.

The quickest way to start is Expo: `npx create-expo-app my-app` then `npx expo start`, and scan the QR code with your phone.

Core Components and Styling

Instead of `div` and `span` you use `View` and `Text`. Styles are JavaScript objects built with `StyleSheet` and use flexbox by default:

tsx
import { View, Text, Pressable, StyleSheet } from 'react-native';
import { useState } from 'react';

export default function App() {
  const [taps, setTaps] = useState(0);

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Tapped {taps} times</Text>
      <Pressable
        style={({ pressed }) => [styles.button, pressed && styles.pressed]}
        onPress={() => setTaps((t) => t + 1)}
        accessibilityRole="button"
      >
        <Text style={styles.label}>Tap me</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, alignItems: 'center', justifyContent: 'center', gap: 16 },
  title: { fontSize: 24, fontWeight: '600' },
  button: { backgroundColor: '#0EA5E9', paddingVertical: 12, paddingHorizontal: 24, borderRadius: 12 },
  pressed: { opacity: 0.7 },
  label: { color: '#fff', fontWeight: '600' },
});

Efficient Lists

Use `FlatList` for long lists. It renders only the rows on screen, which keeps scrolling smooth and memory low. Always provide a stable `keyExtractor`.

tsx
import { FlatList, Text, View, ActivityIndicator } from 'react-native';
import { useEffect, useState } from 'react';

interface Task { id: number; title: string }

export default function TaskList() {
  const [tasks, setTasks] = useState<Task[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch('http://192.168.1.10:8000/tasks')   // your FastAPI server on the LAN
      .then((r) => r.json())
      .then(setTasks)
      .finally(() => setLoading(false));
  }, []);

  if (loading) return <ActivityIndicator size="large" />;

  return (
    <FlatList
      data={tasks}
      keyExtractor={(t) => String(t.id)}
      renderItem={({ item }) => (
        <View style={{ padding: 16 }}>
          <Text>{item.title}</Text>
        </View>
      )}
    />
  );
}

Mobile-Specific Considerations

Phones behave differently from browsers:

  • Use `localhost` only in emulators; physical devices need your computer's network IP.
  • Handle offline states and slow networks gracefully.
  • Store tokens in secure storage, not plain AsyncStorage.
  • Respect safe areas, keyboard overlap and platform conventions.
  • Test on both iOS and Android; small differences matter.

Key Takeaways

  • React Native renders real native views from JavaScript or TypeScript.
  • Expo is the fastest way to start building and testing on a device.
  • FlatList keeps long lists fast by rendering only visible rows.
  • Plan for networking, offline behavior and secure token storage.

Contact Us

Have a question or feedback? Fill out the form below or reach us directly at support@nvaitraining.com