|
| 1 | +# React Native Navigation Architecture |
| 2 | + |
| 3 | +React Native Navigation (RNN) is a native navigation library for React Native that provides 100% native platform navigation on both iOS and Android through a unified JavaScript API. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +- **Package**: `react-native-navigation` (v8.7.0) |
| 8 | +- **Platforms**: iOS 11+, Android 7.0+ (API 24) |
| 9 | +- **React Native**: 0.77+ (developed against 0.83; see package.json for current version) |
| 10 | +- **License**: MIT (maintained by Wix) |
| 11 | + |
| 12 | +## Directory Structure |
| 13 | + |
| 14 | +``` |
| 15 | +react-native-navigation/ |
| 16 | +├── src/ # TypeScript source code (JS API layer) |
| 17 | +├── lib/ # Compiled output (generated by bob build - do not edit) |
| 18 | +├── android/ # Android native implementation (Java/Kotlin) |
| 19 | +├── ios/ # iOS native implementation (Obj-C/C++) |
| 20 | +├── playground/ # Demo app and E2E test target |
| 21 | +├── autolink/ # Post-install linking scripts |
| 22 | +├── scripts/ # Build, test, and release scripts |
| 23 | +├── website/ # Docusaurus documentation site |
| 24 | +├── integration/ # Integration tests (Redux, Remx) |
| 25 | +├── Mock/ # Mock implementations for testing |
| 26 | +└── .buildkite/ # CI/CD pipeline configuration |
| 27 | +``` |
| 28 | + |
| 29 | +## High-Level Architecture |
| 30 | + |
| 31 | +``` |
| 32 | +┌──────────────────────────────────────────────────────────────────┐ |
| 33 | +│ JavaScript API Layer │ |
| 34 | +│ Navigation.setRoot() / push() / pop() / showModal() / etc. │ |
| 35 | +└─────────────────────────────┬────────────────────────────────────┘ |
| 36 | + │ |
| 37 | +┌─────────────────────────────▼────────────────────────────────────┐ |
| 38 | +│ Processing Pipeline │ |
| 39 | +│ OptionsCrawler → LayoutProcessor → LayoutTreeParser → OptionsProcessor │ |
| 40 | +└─────────────────────────────┬────────────────────────────────────┘ |
| 41 | + │ |
| 42 | +┌─────────────────────────────▼────────────────────────────────────┐ |
| 43 | +│ TurboModule Bridge │ |
| 44 | +│ NativeCommandsSender ←→ RNNTurboModule (iOS) / NavigationTurboModule (Android) │ |
| 45 | +└──────────┬─────────────────────────────────────┬─────────────────┘ |
| 46 | + │ │ |
| 47 | +┌──────────▼──────────┐ ┌─────────▼──────────┐ |
| 48 | +│ iOS Native Layer │ │ Android Native Layer│ |
| 49 | +│ UINavigationController │ ViewControllers │ |
| 50 | +│ UITabBarController │ │ CoordinatorLayout │ |
| 51 | +│ UIViewController │ │ BottomNavigation │ |
| 52 | +└─────────────────────┘ └────────────────────┘ |
| 53 | +``` |
| 54 | + |
| 55 | +## Core Concepts |
| 56 | + |
| 57 | +### Layout Types |
| 58 | +All navigation structures are composed from these layout primitives: |
| 59 | + |
| 60 | +| Layout Type | Description | iOS Implementation | Android Implementation | |
| 61 | +|-------------|-------------|-------------------|----------------------| |
| 62 | +| `component` | React component screen | RNNComponentViewController | ComponentViewController | |
| 63 | +| `stack` | Push/pop navigation | UINavigationController (RNNStackController) | StackController | |
| 64 | +| `bottomTabs` | Tab bar navigation | UITabBarController (RNNBottomTabsController) | BottomTabsController | |
| 65 | +| `topTabs` | Horizontal scrollable tabs | RNNTopTabsViewController | TopTabsController | |
| 66 | +| `sideMenu` | Drawer navigation (with center, left, right) | MMDrawerController (RNNSideMenuViewController) | SideMenuController | |
| 67 | +| `splitView` | Master-detail (iPad only) | UISplitViewController (RNNSplitViewController) | — | |
| 68 | +| `externalComponent` | Native (non-React) screen | RNNExternalViewController | ExternalComponentViewController | |
| 69 | + |
| 70 | +### Navigation Commands |
| 71 | +Core commands available through the Navigation API: |
| 72 | + |
| 73 | +- **Root**: `setRoot()` - Replace entire navigation hierarchy |
| 74 | +- **Stack**: `push()`, `pop()`, `popTo()`, `popToRoot()`, `setStackRoot()` |
| 75 | +- **Modal**: `showModal()`, `dismissModal()`, `dismissAllModals()` |
| 76 | +- **Overlay**: `showOverlay()`, `dismissOverlay()`, `dismissAllOverlays()` |
| 77 | +- **Options**: `setDefaultOptions()`, `mergeOptions()`, `updateProps()` |
| 78 | + |
| 79 | +### Options System |
| 80 | +Styling and behavior is controlled via a hierarchical options object: |
| 81 | + |
| 82 | +```typescript |
| 83 | +{ |
| 84 | + statusBar: {...}, // Status bar appearance |
| 85 | + topBar: {...}, // Navigation bar styling |
| 86 | + bottomTabs: {...}, // Tab bar configuration |
| 87 | + bottomTab: {...}, // Individual tab styling |
| 88 | + sideMenu: {...}, // Drawer configuration |
| 89 | + layout: {...}, // Screen layout options |
| 90 | + animations: {...}, // Transition animations |
| 91 | + modal: {...}, // Modal presentation style |
| 92 | + overlay: {...} // Overlay behavior |
| 93 | +} |
| 94 | +``` |
| 95 | + |
| 96 | +Options merge in order: **Default Options → Parent Options → Component Options** |
| 97 | + |
| 98 | +## Data Flow |
| 99 | + |
| 100 | +### Command Execution Flow |
| 101 | +``` |
| 102 | +1. JS: Navigation.push(componentId, layout) |
| 103 | +2. Commands.ts validates and begins processing |
| 104 | +3. OptionsCrawler extracts static options from component classes |
| 105 | +4. LayoutProcessor applies registered layout processors |
| 106 | +5. LayoutTreeParser converts to internal LayoutNode tree |
| 107 | +6. LayoutTreeCrawler processes tree, saves props to Store |
| 108 | +7. OptionsProcessor resolves colors, images, fonts |
| 109 | +8. NativeCommandsSender sends to TurboModule |
| 110 | +9. Native layer creates/updates view hierarchy |
| 111 | +10. EventEmitter sends completion event to JS |
| 112 | +``` |
| 113 | + |
| 114 | +**Note**: The JS layer exports a single `Navigation` object (from `NavigationDelegate`). The TurboModule names differ per platform: `RNNTurboModule` on iOS, `NavigationTurboModule` on Android. |
| 115 | + |
| 116 | +### Event Flow (Native → JS) |
| 117 | +``` |
| 118 | +1. Native lifecycle event (viewDidAppear, etc.) |
| 119 | +2. RNNEventEmitter (iOS) / EventEmitter (Android) |
| 120 | +3. NativeEventsReceiver receives via NativeEventEmitter |
| 121 | +4. EventsRegistry dispatches to registered listeners |
| 122 | +5. ComponentEventsObserver calls component instance methods |
| 123 | +``` |
| 124 | + |
| 125 | +## Key Architecture Patterns |
| 126 | + |
| 127 | +1. **Facade Pattern**: `NavigationDelegate` provides clean public API |
| 128 | +2. **Bridge Pattern**: Adapters isolate JS from native implementation details |
| 129 | +3. **Presenter Pattern**: Separates view styling from controller logic |
| 130 | +4. **Observer Pattern**: Event system for lifecycle and command notifications |
| 131 | +5. **Factory Pattern**: `LayoutFactory` creates controllers from layout nodes |
| 132 | +6. **Plugin Pattern**: Processors allow extending layout/options handling |
| 133 | + |
| 134 | +## Component Lifecycle |
| 135 | + |
| 136 | +React components receive navigation lifecycle events: |
| 137 | + |
| 138 | +```typescript |
| 139 | +class MyScreen extends NavigationComponent { |
| 140 | + componentWillAppear(event) {} // About to become visible |
| 141 | + componentDidAppear(event) {} // Now visible |
| 142 | + componentDidDisappear(event) {} // No longer visible |
| 143 | + navigationButtonPressed(event) {} // TopBar button tapped |
| 144 | + screenPopped(event) {} // Screen removed from stack |
| 145 | + searchBarUpdated(event) {} // Search text changed |
| 146 | + searchBarCancelPressed(event) {} // Search cancelled |
| 147 | + previewCompleted(event) {} // 3D Touch preview completed |
| 148 | +} |
| 149 | +``` |
| 150 | + |
| 151 | +## Testing Architecture |
| 152 | + |
| 153 | +- **Unit Tests**: Jest + ts-mockito for TypeScript source |
| 154 | +- **Integration Tests**: Redux/Remx integration verification |
| 155 | +- **E2E Tests**: Detox framework with playground app |
| 156 | +- **Snapshot Tests**: iOS visual regression testing |
| 157 | +- **Native Unit Tests**: XCTest (iOS) and JUnit (Android) |
| 158 | + |
| 159 | +## Related Documentation |
| 160 | + |
| 161 | +- [JavaScript/TypeScript Architecture](./src/ARCHITECTURE.md) |
| 162 | +- [iOS Native Architecture](./ios/ARCHITECTURE.md) |
| 163 | +- [Android Native Architecture](./android/ARCHITECTURE.md) |
| 164 | +- [API Documentation](https://wix.github.io/react-native-navigation/) |
0 commit comments