# React Native — Cross-Platform Mobile from a Web Mindset

<!-- hint:slides topic="React Native architecture: bridge vs new architecture, core components vs web, platform differences, and navigation" slides="5" -->

## What is React Native?

React Native lets you build native mobile apps (iOS and Android) using JavaScript and React. You write components; RN renders them as native views (not web views).

## Core Components

React Native uses different primitives than the web:

| Component | Purpose | Web Analogy |
|-----------|---------|-------------|
| `View` | Container, layout | `<div>` |
| `Text` | Display text | `<p>`, `<span>` |
| `ScrollView` | Scrollable container | Overflow scroll |
| `FlatList` | Virtualized list | Virtual list |
| `Image` | Images | `<img>` |
| `TextInput` | User input | `<input>` |
| `TouchableOpacity` | Pressable area | `<button>` |

**Rule:** All text must be inside `<Text>`. You cannot put text directly in `<View>`.

```jsx
<View>
  <Text>Hello, world!</Text>
</View>
```

## StyleSheet

Use `StyleSheet.create()` for styles. Properties are camelCase; no CSS classes:

```jsx
const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
    backgroundColor: '#fff',
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
  },
});
```

Flexbox is the default layout. Use `flex: 1` to fill space. `flexDirection` defaults to `column` (not `row`).

## FlatList

For long lists, use `FlatList` (virtualized) instead of mapping over an array:

```jsx
<FlatList
  data={items}
  keyExtractor={(item) => item.id}
  renderItem={({ item }) => <ItemRow item={item} />}
/>
```

`FlatList` only renders visible items + buffer — essential for performance.

## Navigation (React Navigation)

React Navigation is the standard for screen navigation:

```jsx
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}
```

Navigate with `navigation.navigate('Details', { id: 1 })`. Access params via `route.params`.

## Platform Differences

Use `Platform.OS` or `Platform.select()`:

```jsx
import { Platform } from 'react-native';

const padding = Platform.select({ ios: 20, android: 16 });
// Or: Platform.OS === 'ios' ? 20 : 16
```

Some components behave differently (e.g., `TextInput`, shadows). Test on both platforms.

## Expo vs Bare

| | Expo | Bare (React Native CLI) |
|---|-----|------------------------|
| Setup | Fast, no Xcode/Android Studio needed to start | Full native setup |
| Native modules | Limited to Expo SDK + config plugins | Full access |
| Build | EAS Build (cloud) or local | Xcode, Android Studio |
| Use case | Prototypes, most apps | Heavy native customization |

## Architecture: How It Works

React Native bridges JavaScript and native code:

```mermaid
flowchart LR
    subgraph JS
        A[JS Thread]
    end
    subgraph Bridge
        B[Bridge]
    end
    subgraph Native
        C[Native Thread]
    end
    A <-->|Serialized messages| B
    B <-->|Native calls| C
```

- **JS Thread:** Runs your React code, handles logic
- **Bridge:** Serializes commands (e.g., "create View", "set style")
- **Native Thread:** Renders actual UI, handles touch events

The bridge can be a bottleneck. New Architecture (Fabric, TurboModules) reduces this.

## Common Gotchas

- **No div/span:** Use `View` and `Text` only
- **No className:** Use `style` prop with StyleSheet
- **Pixel density:** Use `Dimensions.get('window')` or layout APIs for responsive sizing
- **Keyboard:** Use `KeyboardAvoidingView` for forms
