Upload
software-guru
View
654
Download
0
Embed Size (px)
Citation preview
Cross PlatformDevelopmentwith React NativeKen Wheeler | @ken_wheeler
What is ReactNative?
Cross platform native app library
Write native apps in Javascript
Renders to real native UI
First, lets talkabout React
UI library developed at Facebook
Pitched as "just the view layer"
Robust component system
Virtual DOM
The new hotness
class Test extends React.Component { render() { return ( <div> <p>I'm a component!</p> </div> ) } }
JSX<div> <p>I'm a component!</p> </div> React.DOM.div(null, React.DOM.p(null, "I'm a component!") );
Propsclass Test extends React.Component { render() { return <p>{this.props.name}</p> } } //Usage <Test name="Ken"/>
Prop ValidationTest.propTypes = { name: PropTypes.string }; Test.defaultProps = { name: "Default" };
Stateclass Test extends React.Component { state = { count: 1 }; render() { return <p>{this.state.count}</p> } }
setStatethis.setState({ count: 2 });
Eventsclass Test extends React.Component { increment() { ... } render() { return ( <button onClick={this.increment}> Increment </button> ); } }
ComponentLifecycle
componentWillMountcomponentDidMountcomponentWillUnmount
componentWillReceivePropscomponentWillUpdatecomponentDidUpdateshouldComponentUpdate
What about data?
Unidirectional Data Flow
Flux Architecture
Smart Components
Reduxhttps://github.com/reactjs/redux
Relayhttps://github.com/facebook/relay
RxJShttps://github.com/ReactiveX/RxJS
React Native
Why use React Native?
Cross Platform
"Native Feel"
One Language
Live Reload
OTA Updates
Why is makes sense forbusiness
Fast Development Cycles
Fast Deployment Cycle
Resource Interoperability
One Team
How React Native Works
Primitivesclass Test extends React.Component { render() { return ( <View> <Text>I'm a component!</Text> </View> ) } }
View Components
ViewTextImageListViewMapViewNavigatorScrollView
ModalPicker
RefreshControlSwitchTextInputWebViewTouchable*
Device APIs
AlertAnimatedAppState
AsyncStorageCameraRollDimensions
LinkingNetInfoPixelRatioPanResponderStyleSheet
LayoutAnimation
Poly�lls
FlexboxGeolocationNetworkTimersColors
Networking
Fetchfetch(API_URL) .then(res => res.json()) .then(data => { console.log(data); }) .catch(error => { console.warn(error); });
Async/Awaitasync function getData() { try { const res = await fetch(API_URL); const data = await res.json(); console.log(data); } catch(e) { console.warn(e) } }
Styling & Layout
StyleSheetconst styles = StyleSheet.create({ container: { backgroundColor: "#ccc", padding: 10, margin: 10, borderRadius: 3, borderWidth: 2 } });
Applying Stylesclass Container extends React.Component { render() { return ( <View style={styles.container}/> //... child components </View> ) } }
Flexboxconst styles = StyleSheet.create({ layout: { flexDirection: "row", alignItems: "center", justifyContent: "center" }, tiles: { flex: 1 } });
Custom iOSModules
// MyModule.h #import "RCTBridgeModule.h" @interface MyModule : NSObject <RCTBridgeModule> @end
// MyModule.m @implementation MyModule RCT_EXPORT_MODULE(); RCT_EXPORT_METHOD(sayName:(NSString *)name){ RCTLogInfo(@"My name is %@", name); } @end // Usage in Javascript: NativeModules.MyModule.sayName("Ken");
RCT_EXPORT_METHOD(getData:(RCTResponseSenderBlock)callback) { NSArray *data = ... callback(@[data]); } // Usage in Javascript: NativeModules.MyModule.getData(data => { console.log(data); });
RCT_REMAP_METHOD(getData, resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { NSArray *data = ... if (data) { resolve(data); } else { NSError *error = ... reject(@"no_data", @"Data fetch error", data); } } // Usage in Javascript: NativeModules.MyModule.getData .then(data => console.log(data)) .catch(err => console.log(err));
Custom AndroidModules
public class MyModule extends ReactContextBaseJavaModule { public MyModule(ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { return "MyModule"; } @ReactMethod public void sayName(String name) { Log.v("MyModule", "My name is " + name); } } // Usage in Javascript: NativeModules.MyModule.sayName("Ken");
@ReactMethod public void getData(Callback errorCallback, Callback successCallback try { float data = // ...get data; successCallback.invoke(data); } catch (IllegalViewOperationException e) { errorCallback.invoke(e.getMessage()); } } // Usage in Javascript: NativeModules.MyModule.getData( (err) => console.log(err), (data) => console.log(data) );
@ReactMethod public void getData(Promise promise) { try { float data = // ...get data; promise.resolve(data); } catch (IllegalViewOperationException e) { promise.reject(e); } } // Usage in Javascript: NativeModules.MyModule.getData .then(data => console.log(data)) .catch(err => console.log(err));
iOS ViewComponents
@interface RCTMapView : RCTViewManager @end @implementation RCTMapManager RCT_EXPORT_MODULE() RCT_EXPORT_VIEW_PROPERTY(mapType, MKMapType) - (UIView *)view { return [[MKMapView alloc] init]; } @end //Usage in javascript const RCTMap = requireNativeComponent('RCTMap', null);
Android ViewComponents
public class ReactMapManager extends SimpleViewManager<MapView> @Override public String getName() { return "RCTMapView"; } @ReactProp(name = "mapType") public void setMapType(ReactMapView view, @Nullable int mapType googleMap.getMap().setMapType(mapType); } @Override public ReactMapView createViewInstance(ThemedReactContext context return new MapView(context, Fresco.newDraweeControllerBuilder } } //Usage in javascript const RCTMap = requireNativeComponent('RCTMap', null);
React NativeTooling
DebuggingChrome Devtools
Nuclide
Redbox
Yellowbox
Pro�lingSystrace
Perf Monitor
Instruments (iOS)
JS Tooling
ES6const add = (a, b) => a + b; // Arrow functions let { name, address, ...info } = this.props; // Destructuring let state = { // Object rest spreads ...state, name }; class Test { // ES6 Classes getName() { return "Test"; } }
Flowtypefunction getData(url: string, callback: Function): Object { return fetch(url) .then(res => res.json()) .then(data => callback(data)); }
TestingMocha/Jest
react-addons-test-utils
Enzyme
react-native-mock
Appium
Third PartyTooling
AppHub
CodePush
Reindex
AppBoy
RNPM
Om & Elm Native
ExponentJSNo Xcode required
Distribute apps to anyone with theapp
Exponent XDE
Exponent App
Available in the App Store
Demoexp://exp.host/@thekenwheeler/mobile-day-demo