KEMBAR78
React Native for ReactJS Devs | PPTX
REACT NATIVE FOR REACT
DEVELOPERS
Barak Cohen, Wondermall
FRONT-END IS BROKEN
• Build the same app 3-6 times: iOS (Phone/Tablet),
Android (Phone/Tablet), Web (Desktop/Phone)
• Different teams build the same thing using 3
different languages, frameworks & libraries.
• Hard to maintain feature parity & consistent
terminology.
• Impossible to be an expert in all technologies and
“own” something in all products
STACK-CENTRIC R&D
iOS
Product Manager
Web Android
iOS Dev
iOS Dev
iOS Dev
Web Dev
Web Dev
Web Dev
Android Dev
Android Dev
Android Dev
BUSINESS-CENTRIC R&D
Feature A
Product Manager
Feature B Feature C
Full-Stack Dev
Full-Stack Dev
Full-Stack Dev
Full-Stack Dev
Full-Stack Dev
Full-Stack Dev
Full-Stack Dev
Full-Stack Dev
Full-Stack Dev
FULL-STACK IS HARD!
• Almost all devs at Wondermall do Python, ObjC+Swift
and AngularJS
• Level of expertise vary. No one is a rock star on all 3
platforms
• We’ll never get everyone cross trained on Android,
Windows Phone, Apple Watch, Apple TV, …
• If we want to remain Full Stack, we’ll have to rethink our
strategy
Powered by React-Native
BASICS
REACT-NATIVE IS…
• JavaScript for Application Logic
• Native UI (No WebViews)
• Flexbox Layout
• Polyfills (fetch API) & Platform APIs
(Camera)
• Compatible with nearly all React and JS libs
GETTING STARTED
$ brew install node && brew install watchman
$ npm install -g react-native-cli
$ react-native init MyProject && cd MyProject
$ react-native run-ios
HELLO WORLD
var React = require('react')
var { View, Text } = require('react-native')
class HelloWorldView extends React.Component {
render() {
return (
<View><Text>Hello World</Text></View>
)
}
}
React DOM React Native
React
React Canvas React Three
iOS Android macOS Win 10 Web
REACT ECO-SYSTEM
Tizen
REACT (NATIVE+JS)
BENEFITS
• “Learn once write anywhere”
• Reuse almost all non-UI code across all
platforms
• Reuse most UI code between Native
Platforms
• Hot-reloading JS, debug in Chrome
BENEFITS - CON’T
• Can be added incrementally to an existing
app
• Over-the-wire updates w/o AppStore
(AppHub)
• JS w/ ES6 is succinct and productive
• Can use previously written native code and
UI
STYLE & LAYOUT
ADDING STYLE
class HelloWorldView extends React.Component {
...
render() {
return (
<View style={{padding: 10}}>
<Text style={{fontSize: 14, color: '#0000ff'}}>
Hello World
</Text>
</View>
)
}
}
FLEXBOX LAYOUT
class HelloWorldView extends React.Component {
render() {
return (
<View style={{flexDirection: 'column', flex: 1}}>
<View style={{flex: 1, backgroundColor: 'red'}}></View>
<View style={{flex: 1, backgroundColor: 'green'}}></View>
<View style={{flex: 1, backgroundColor: 'blue'}}></View>
</View>
)
}
}
FLEXBOX LAYOUT - 2
class HelloWorldView extends React.Component {
render() {
return (
<View style={{flexDirection: 'row', flex: 1}}>
<View style={{flex: 1, backgroundColor: 'red'}}></View>
<View style={{flex: 1, backgroundColor: 'green'}}></View>
<View style={{flex: 1, backgroundColor: 'blue'}}></View>
</View>
)
}
}
NATIVE APIS
import React, { Component } from 'react';
import { MapView } from 'react-native';
class MapMyRide extends Component {
render() {
return (
<MapView
style={{height: 200, margin: 40}}
showsUserLocation={true}
/>
);
}
}
ROUTING
return (
<Navigator
initialRoute={{ title: 'My Initial Scene', index: 0 }}
renderScene={(route, navigator) =>
<MyScene
title={route.title}
onForward={ () => {
navigator.push({
title: 'Scene ' + route.index + 1,
index: route.index + 1,
});
}}
/>
}
/>
)
BUILT-IN
REACT-NATIVE-ROUTER-
FLUX
import { PageOne, PageTwo } from './Pages';
export default class App extends Component {
render() {
return (
<Router>
<Scene key="root">
<Scene key="pageOne" component={PageOne} title="PageOne" initial={true} />
<Scene key="pageTwo" component={PageTwo} title="PageTwo" />
</Scene>
</Router>
)
}
}
UNIVERSAL APPS
Shared - Native & Web
Redux /
Relay
API Client
Business
Logic
Shared Native
Native Specific
<TabBarIOS>,
<AndroidToolbar>
<Text>, <TextInput>,
<Image>
Web
<div>
Business Level Comp’
<span>
<img>
DEBUGGING & TOOLING
• Reload - Clears all JS code and resets
the state
• Remote JS Debugging - Chrome /
VSCode with breakpoints and Console
(no network)
• Live Reload - Automatic Reload (as
above)
• Hot Reloading - Change JS code without
DEVELOPER MENU
REDUX REMOTE DEV
TOOLS
PACKAGER
• Built-in packager with ES6 support
• Development: local webserver serves the
bundled JS
• Production:
• Use .ios.js or .android.js suffixes, Packager will
include the correct file for the platform bundle
$ react-native bundle —platform ios
OTA UPDATES
• Updates JS & assets without AppStore submission
• Apple’s policy allows it for fixes & minor
improvements
• Microsoft CodePush - Commercial
• AppHub - Hosted / OSS
INTEGRATION &
INTERNALS
NATIVE VS. JAVASCRIPT
View Controller
View Controller
View Controller Bridge
(incl. JS VM)
JavaScript FileJavaScript FileJavaScript File
RCTRootView
UIView
UIView
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions…
{
NSURL *jsCodeLocation = @“http://localhost:8081/index.ios.bundle?platform=ios";
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"MyComponent"
initialProperties:@{}
launchOptions:launchOptions];
UIViewController *rootViewController = [[UIViewController alloc] init];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
}
MULTIPLE RCTROOTVIEWS
RCTRootView
UIView
UIView
RCTRootView
UIView
UIView
Bridge
(incl. JS VM)
{
// AppDelegate didFinishLaunchingWithOptions
self.bridge = [[RCTBridge alloc] initWithBundleURL:@"localhost..."
moduleProvider:nil
launchOptions:nil]
// When you want to show R/N view
[[RCTRootView alloc] initWithBridge:self.bridge
moduleName:"MyComponent"];
// Somewhere else
[[RCTRootView alloc] initWithBridge:self.bridge
moduleName:"MyOtherComponent"];
}
NATIVE MODULES
• Export native functions to be called from JS
• Export constants and enums
• Send events to JS from native
• They are singletons
// CalendarManager.h
#import "RCTBridgeModule.h"
@interface CalendarManager : NSObject <RCTBridgeModule>
@end
// CalendarManager.m
@implementation CalendarManager
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(addEvent:(NSString *)name
location:(NSString *)location)
{
RCTLogInfo(@“Creating event %@ at %@", name, location);
}
@end
RETURN VALUE W/
PROMISES
RCT_EXPORT_METHOD(findEvents,
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSArray *events = ...
if (events) {
resolve(events);
} else {
NSError *error = ...
reject(@"no_events", @"There were no events", error);
}
}
import { NativeModules } from ‘react-native';
CalendarManager = NativeModules.CalendarManager;
CalendarManager.addEvent(‘Birthday Party’, …);
async function updateEvents() {
try {
var events = await CalendarManager.findEvents();
this.setState({ events });
} catch (e) {
console.error(e);
}
}
updateEvents();
MISC.
PERFORMANCE TIPS
• Minimize bridge messages
• Implement shouldComponentUpdate
• Direct Manipulation with setNativeProps
• Rewrite in Native
FURTHER READING
• Facebook’s F8 App - http://makeitopen.com/
• React Native Newsletter -
http://reactnative.cc/
• Practice layout and Flexbox
https://github.com/jondot/ReactNativeKatas
• https://github.com/jondot/awesome-react-
native
STARTER KITS
• Native Starter -
http://startreact.com/themes/native-starter/
• Ignite - https://github.com/infinitered/ignite
• este.js - https://github.com/este/este
3RD-PARTY COMPONENTS
• https://js.coach/react-native/
• https://react.parts/native
• nativebase.io
THANK YOU!
(QUESTIONS?)

React Native for ReactJS Devs

  • 1.
    REACT NATIVE FORREACT DEVELOPERS Barak Cohen, Wondermall
  • 3.
    FRONT-END IS BROKEN •Build the same app 3-6 times: iOS (Phone/Tablet), Android (Phone/Tablet), Web (Desktop/Phone) • Different teams build the same thing using 3 different languages, frameworks & libraries. • Hard to maintain feature parity & consistent terminology. • Impossible to be an expert in all technologies and “own” something in all products
  • 4.
    STACK-CENTRIC R&D iOS Product Manager WebAndroid iOS Dev iOS Dev iOS Dev Web Dev Web Dev Web Dev Android Dev Android Dev Android Dev
  • 5.
    BUSINESS-CENTRIC R&D Feature A ProductManager Feature B Feature C Full-Stack Dev Full-Stack Dev Full-Stack Dev Full-Stack Dev Full-Stack Dev Full-Stack Dev Full-Stack Dev Full-Stack Dev Full-Stack Dev
  • 6.
    FULL-STACK IS HARD! •Almost all devs at Wondermall do Python, ObjC+Swift and AngularJS • Level of expertise vary. No one is a rock star on all 3 platforms • We’ll never get everyone cross trained on Android, Windows Phone, Apple Watch, Apple TV, … • If we want to remain Full Stack, we’ll have to rethink our strategy
  • 7.
  • 8.
  • 9.
    REACT-NATIVE IS… • JavaScriptfor Application Logic • Native UI (No WebViews) • Flexbox Layout • Polyfills (fetch API) & Platform APIs (Camera) • Compatible with nearly all React and JS libs
  • 10.
    GETTING STARTED $ brewinstall node && brew install watchman $ npm install -g react-native-cli $ react-native init MyProject && cd MyProject $ react-native run-ios
  • 11.
    HELLO WORLD var React= require('react') var { View, Text } = require('react-native') class HelloWorldView extends React.Component { render() { return ( <View><Text>Hello World</Text></View> ) } }
  • 12.
    React DOM ReactNative React React Canvas React Three iOS Android macOS Win 10 Web REACT ECO-SYSTEM Tizen
  • 13.
    REACT (NATIVE+JS) BENEFITS • “Learnonce write anywhere” • Reuse almost all non-UI code across all platforms • Reuse most UI code between Native Platforms • Hot-reloading JS, debug in Chrome
  • 14.
    BENEFITS - CON’T •Can be added incrementally to an existing app • Over-the-wire updates w/o AppStore (AppHub) • JS w/ ES6 is succinct and productive • Can use previously written native code and UI
  • 15.
  • 16.
    ADDING STYLE class HelloWorldViewextends React.Component { ... render() { return ( <View style={{padding: 10}}> <Text style={{fontSize: 14, color: '#0000ff'}}> Hello World </Text> </View> ) } }
  • 17.
    FLEXBOX LAYOUT class HelloWorldViewextends React.Component { render() { return ( <View style={{flexDirection: 'column', flex: 1}}> <View style={{flex: 1, backgroundColor: 'red'}}></View> <View style={{flex: 1, backgroundColor: 'green'}}></View> <View style={{flex: 1, backgroundColor: 'blue'}}></View> </View> ) } }
  • 18.
    FLEXBOX LAYOUT -2 class HelloWorldView extends React.Component { render() { return ( <View style={{flexDirection: 'row', flex: 1}}> <View style={{flex: 1, backgroundColor: 'red'}}></View> <View style={{flex: 1, backgroundColor: 'green'}}></View> <View style={{flex: 1, backgroundColor: 'blue'}}></View> </View> ) } }
  • 19.
    NATIVE APIS import React,{ Component } from 'react'; import { MapView } from 'react-native'; class MapMyRide extends Component { render() { return ( <MapView style={{height: 200, margin: 40}} showsUserLocation={true} /> ); } }
  • 20.
  • 21.
    return ( <Navigator initialRoute={{ title:'My Initial Scene', index: 0 }} renderScene={(route, navigator) => <MyScene title={route.title} onForward={ () => { navigator.push({ title: 'Scene ' + route.index + 1, index: route.index + 1, }); }} /> } /> ) BUILT-IN
  • 22.
    REACT-NATIVE-ROUTER- FLUX import { PageOne,PageTwo } from './Pages'; export default class App extends Component { render() { return ( <Router> <Scene key="root"> <Scene key="pageOne" component={PageOne} title="PageOne" initial={true} /> <Scene key="pageTwo" component={PageTwo} title="PageTwo" /> </Scene> </Router> ) } }
  • 23.
  • 24.
    Shared - Native& Web Redux / Relay API Client Business Logic Shared Native Native Specific <TabBarIOS>, <AndroidToolbar> <Text>, <TextInput>, <Image> Web <div> Business Level Comp’ <span> <img>
  • 25.
  • 26.
    • Reload -Clears all JS code and resets the state • Remote JS Debugging - Chrome / VSCode with breakpoints and Console (no network) • Live Reload - Automatic Reload (as above) • Hot Reloading - Change JS code without DEVELOPER MENU
  • 27.
  • 28.
    PACKAGER • Built-in packagerwith ES6 support • Development: local webserver serves the bundled JS • Production: • Use .ios.js or .android.js suffixes, Packager will include the correct file for the platform bundle $ react-native bundle —platform ios
  • 29.
    OTA UPDATES • UpdatesJS & assets without AppStore submission • Apple’s policy allows it for fixes & minor improvements • Microsoft CodePush - Commercial • AppHub - Hosted / OSS
  • 30.
  • 31.
    NATIVE VS. JAVASCRIPT ViewController View Controller View Controller Bridge (incl. JS VM) JavaScript FileJavaScript FileJavaScript File RCTRootView UIView UIView
  • 32.
    - (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions… { NSURL *jsCodeLocation = @“http://localhost:8081/index.ios.bundle?platform=ios"; RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"MyComponent" initialProperties:@{} launchOptions:launchOptions]; UIViewController *rootViewController = [[UIViewController alloc] init]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; }
  • 33.
  • 34.
    { // AppDelegate didFinishLaunchingWithOptions self.bridge= [[RCTBridge alloc] initWithBundleURL:@"localhost..." moduleProvider:nil launchOptions:nil] // When you want to show R/N view [[RCTRootView alloc] initWithBridge:self.bridge moduleName:"MyComponent"]; // Somewhere else [[RCTRootView alloc] initWithBridge:self.bridge moduleName:"MyOtherComponent"]; }
  • 35.
    NATIVE MODULES • Exportnative functions to be called from JS • Export constants and enums • Send events to JS from native • They are singletons
  • 36.
    // CalendarManager.h #import "RCTBridgeModule.h" @interfaceCalendarManager : NSObject <RCTBridgeModule> @end // CalendarManager.m @implementation CalendarManager RCT_EXPORT_MODULE(); RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location) { RCTLogInfo(@“Creating event %@ at %@", name, location); } @end
  • 37.
    RETURN VALUE W/ PROMISES RCT_EXPORT_METHOD(findEvents, resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { NSArray*events = ... if (events) { resolve(events); } else { NSError *error = ... reject(@"no_events", @"There were no events", error); } }
  • 38.
    import { NativeModules} from ‘react-native'; CalendarManager = NativeModules.CalendarManager; CalendarManager.addEvent(‘Birthday Party’, …); async function updateEvents() { try { var events = await CalendarManager.findEvents(); this.setState({ events }); } catch (e) { console.error(e); } } updateEvents();
  • 39.
  • 40.
    PERFORMANCE TIPS • Minimizebridge messages • Implement shouldComponentUpdate • Direct Manipulation with setNativeProps • Rewrite in Native
  • 41.
    FURTHER READING • Facebook’sF8 App - http://makeitopen.com/ • React Native Newsletter - http://reactnative.cc/ • Practice layout and Flexbox https://github.com/jondot/ReactNativeKatas • https://github.com/jondot/awesome-react- native
  • 42.
    STARTER KITS • NativeStarter - http://startreact.com/themes/native-starter/ • Ignite - https://github.com/infinitered/ignite • este.js - https://github.com/este/este
  • 43.
    3RD-PARTY COMPONENTS • https://js.coach/react-native/ •https://react.parts/native • nativebase.io
  • 44.

Editor's Notes

  • #2 Agenda: Motivation Basics Eco-System + Benefits Styling, Layout & Routing Universal Apps Debugging & Tooling Internals Misc Who has Redux exp.? Who has R/N exp.?
  • #3 React Native appears to both JS (“Web”) developers & Native developers
  • #10 Runs on a separate thread, doesn’t block UI, talks to Native via a bridge. Reuse the enormous JS ecosystem. Wrapped by JS and touched only by the framework Fast (transpiled to C and Java), Flexible, much easier than AutoLayout
  • #11 Generates standard iOS and Android projects that create a normal binary distribution
  • #12 ES6 destructors + Class syntax (mention constructor, super) JSX
  • #14 Same techniques, libraries, mental models. Become an “Uberstack Developer” Web has different form factor so re-build the UI anyway. iOS and Android have diff standard components. FB Ads Manager (iOS & Android) reused 90% for Android
  • #15 Great way to give it a try w/o betting the company Has great implications on testing strategy, fast response to bugs. Lambdas, Class syntax Can bring pure-native components if RN is lacking or want to leverage previous investments.
  • #18 Flex value > 0 means “fill in the parent”. Then, flex divides the space relative to the value.
  • #23 Integrates tab and navigation stack (back button)
  • #25 API Client - fetch polypill For web - consider React-Native-Web
  • #29 Production: JS packaged into the binary distribution
  • #30 Crashlytics Integration
  • #32 RCTRootView is a subclass of UIView It can be the only thing in your app or just another “screen” You can have several such views sharing a bridge
  • #34 Share the context, e.g. Redux state Use AppRegistry.registerComponent for each root component that RCTRoowViewLoads
  • #39 Native UI Components - RCTViewManager, mapped properties https://github.com/wix/react-native-invoke
  • #41 Direct Manipulation - Equivalent of setting a DOM node’s properties directly setNativeProps avoids re-rendering the Component
  • #42 FB’s F8 app in R/N Practice RN Layouts w/ Flexbox by Dotan Nahum
  • #43 Basic starter - integrates w/ Redux & DevTools, local-storage, NativeBase Adds React Sagas, testing libs, integrated native components Heavy-weight - includes Web & server side rendering, webpack. Somewhat outdated