Skip to content

Latest commit

 

History

History
164 lines (136 loc) · 8.38 KB

File metadata and controls

164 lines (136 loc) · 8.38 KB

React Native Navigation Architecture

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.

Project Overview

  • Package: react-native-navigation (v8.7.0)
  • Platforms: iOS 11+, Android 7.0+ (API 24)
  • React Native: 0.77+ (developed against 0.83; see package.json for current version)
  • License: MIT (maintained by Wix)

Directory Structure

react-native-navigation/
├── src/                    # TypeScript source code (JS API layer)
├── lib/                    # Compiled output (generated by bob build - do not edit)
├── android/                # Android native implementation (Java/Kotlin)
├── ios/                    # iOS native implementation (Obj-C/C++)
├── playground/             # Demo app and E2E test target
├── autolink/               # Post-install linking scripts
├── scripts/                # Build, test, and release scripts
├── website/                # Docusaurus documentation site
├── integration/            # Integration tests (Redux, Remx)
├── Mock/                   # Mock implementations for testing
└── .buildkite/             # CI/CD pipeline configuration

High-Level Architecture

┌──────────────────────────────────────────────────────────────────┐
│                     JavaScript API Layer                         │
│  Navigation.setRoot() / push() / pop() / showModal() / etc.     │
└─────────────────────────────┬────────────────────────────────────┘
                              │
┌─────────────────────────────▼────────────────────────────────────┐
│                    Processing Pipeline                            │
│  OptionsCrawler → LayoutProcessor → LayoutTreeParser → OptionsProcessor │
└─────────────────────────────┬────────────────────────────────────┘
                              │
┌─────────────────────────────▼────────────────────────────────────┐
│                   TurboModule Bridge                              │
│  NativeCommandsSender ←→ RNNTurboModule (iOS) / NavigationTurboModule (Android) │
└──────────┬─────────────────────────────────────┬─────────────────┘
           │                                     │
┌──────────▼──────────┐               ┌─────────▼──────────┐
│   iOS Native Layer  │               │ Android Native Layer│
│  UINavigationController             │   ViewControllers   │
│  UITabBarController │               │   CoordinatorLayout │
│  UIViewController   │               │   BottomNavigation  │
└─────────────────────┘               └────────────────────┘

Core Concepts

Layout Types

All navigation structures are composed from these layout primitives:

Layout Type Description iOS Implementation Android Implementation
component React component screen RNNComponentViewController ComponentViewController
stack Push/pop navigation UINavigationController (RNNStackController) StackController
bottomTabs Tab bar navigation UITabBarController (RNNBottomTabsController) BottomTabsController
topTabs Horizontal scrollable tabs RNNTopTabsViewController TopTabsController
sideMenu Drawer navigation (with center, left, right) MMDrawerController (RNNSideMenuViewController) SideMenuController
splitView Master-detail (iPad only) UISplitViewController (RNNSplitViewController)
externalComponent Native (non-React) screen RNNExternalViewController ExternalComponentViewController

Navigation Commands

Core commands available through the Navigation API:

  • Root: setRoot() - Replace entire navigation hierarchy
  • Stack: push(), pop(), popTo(), popToRoot(), setStackRoot()
  • Modal: showModal(), dismissModal(), dismissAllModals()
  • Overlay: showOverlay(), dismissOverlay(), dismissAllOverlays()
  • Options: setDefaultOptions(), mergeOptions(), updateProps()

Options System

Styling and behavior is controlled via a hierarchical options object:

{
  statusBar: {...},      // Status bar appearance
  topBar: {...},         // Navigation bar styling
  bottomTabs: {...},     // Tab bar configuration
  bottomTab: {...},      // Individual tab styling
  sideMenu: {...},       // Drawer configuration
  layout: {...},         // Screen layout options
  animations: {...},     // Transition animations
  modal: {...},          // Modal presentation style
  overlay: {...}         // Overlay behavior
}

Options merge in order: Default Options → Parent Options → Component Options

Data Flow

Command Execution Flow

1. JS: Navigation.push(componentId, layout)
2. Commands.ts validates and begins processing
3. OptionsCrawler extracts static options from component classes
4. LayoutProcessor applies registered layout processors
5. LayoutTreeParser converts to internal LayoutNode tree
6. LayoutTreeCrawler processes tree, saves props to Store
7. OptionsProcessor resolves colors, images, fonts
8. NativeCommandsSender sends to TurboModule
9. Native layer creates/updates view hierarchy
10. EventEmitter sends completion event to JS

Note: The JS layer exports a single Navigation object (from NavigationDelegate). The TurboModule names differ per platform: RNNTurboModule on iOS, NavigationTurboModule on Android.

Event Flow (Native → JS)

1. Native lifecycle event (viewDidAppear, etc.)
2. RNNEventEmitter (iOS) / EventEmitter (Android)
3. NativeEventsReceiver receives via NativeEventEmitter
4. EventsRegistry dispatches to registered listeners
5. ComponentEventsObserver calls component instance methods

Key Architecture Patterns

  1. Facade Pattern: NavigationDelegate provides clean public API
  2. Bridge Pattern: Adapters isolate JS from native implementation details
  3. Presenter Pattern: Separates view styling from controller logic
  4. Observer Pattern: Event system for lifecycle and command notifications
  5. Factory Pattern: LayoutFactory creates controllers from layout nodes
  6. Plugin Pattern: Processors allow extending layout/options handling

Component Lifecycle

React components receive navigation lifecycle events:

class MyScreen extends NavigationComponent {
  componentWillAppear(event) {}      // About to become visible
  componentDidAppear(event) {}       // Now visible
  componentDidDisappear(event) {}    // No longer visible
  navigationButtonPressed(event) {}  // TopBar button tapped
  screenPopped(event) {}             // Screen removed from stack
  searchBarUpdated(event) {}         // Search text changed
  searchBarCancelPressed(event) {}   // Search cancelled
  previewCompleted(event) {}         // 3D Touch preview completed
}

Testing Architecture

  • Unit Tests: Jest + ts-mockito for TypeScript source
  • Integration Tests: Redux/Remx integration verification
  • E2E Tests: Detox framework with playground app
  • Snapshot Tests: iOS visual regression testing
  • Native Unit Tests: XCTest (iOS) and JUnit (Android)

Related Documentation