Adding React Native to the "mix"

Adam Pelle

 Agenda


  1. Why React Native?

  2. Organizing the code

  3. Native modules

  4. Native UI components

  5. Recap

 React Native @skyscanner


  • Mobile first organization strategy
  • ~40 mobile, ~200 web/backend engineers
  • how can we execute the plan?
  • Already betting react on the web...
  • Additional benefits: code reuse, live reloading

 Getting started...


  • Investigation started ~ early 2017
    • technical feasibility
    • co-existence with already huge native codebase?
    • Long term support (LTS)
      • licensing
      • apple dynamic code execution
      • google x64 requirement
    • javascript adoption in native community
  • "brown-field" situation <-> green field

Let's start with a non-essential feature!

 Let's rollin'...


  • Validation of the concept
  • Create an "Error page"
    • shows when something really bad happened
    • ~ HTTP 5xx server error pages on the web
  • Simple UI

 The first real challenge


  Organizing the code


  • how to integrate React codebase?
    • ios, android repo
    • single React Native (RN) repository
    • mono repository
  • we started with copy-pasting :)
  • next step: investigating single RN repository
    • JS codes live in their own repo
    • integration via git submodules, npm or push

  Multi repository


  Mono repository


  • Issues with multi repo
    • significant delay between initial push, app master
    • testing in js repo without context
    • how to live in isolation? -> mocking platform?
  • Mono repository FTW!
  • Single CI pipeline for ios, android, RN
    • still complex to run tests exclusively
    • need appropriate infrastructure

 Native Modules - "bridges"


  • Bridging between native and JS side
  • Very powerful tool
  • We have bridges for all the "platform" features

 Use case: navigation


  • native -> react native
    • every RN screen is a View Controller
  • react native -> native
    • custom navigation framework support
  • react native -> react native
    • third party frameworks (e.g react-navigation)
    • navigation framework
      • RN -> native -> RN
      • redux store to save/load app state

 Testing Native Modules


  • Unit test from native side (simple)
  • Integration tests between native <-> JS communication (hard)
    • bootstrap JS bundle start an RCTView
    • assertion on both side

Testing React Native iOS Bridges

by Szabolcs Tóth

 Native UI Components


  • Use entire native components not only the logic
    • existing views
    • third party views not available for RN
  • Super handy for brown field apps
    • incrementally porting pages to RN
    • component libraries

 Use case: Backpack


 Complexity


  • React native "takes over" the native view
    • resets couple properties (e.g frame, styles)
    • -> wrapper view
  • Conflicting layout systems
    • YOGA <--> Autolayout
- (void)layoutSubviews {
    CGSize size = [self.inner
                systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

    RCTExecuteOnUIManagerQueue(^{
        RCTShadowView *shadowView = [self.bridge.uiManager
                                        shadowViewForReactTag:self.reactTag];
        shadowView.intrinsicContentSize = size;
    });
}

 Problems


  • Not for the faint of heart
    • need to be expect in RN/IOS
  • Non deterministic
    • "layoutSubviews" called on different threads
    • every UI related operation is async from non-UI thread

 Verdict


  • Properly assess use cases and viability
  • React philosophy
    • Epoxy 
  • Scaling up mobile development
  • continuously improving
  • Sometimes makes a trivial task significantly convoluted from native POV
  • Animations are not mature
  • Javascript is not everyone's type :)

Q & A

We are hiring!