Date post: | 15-Apr-2017 |
Category: |
Engineering |
Upload: | matteo-manchi |
View: | 851 times |
Download: | 1 times |
React-Nativefor multi-platform mobile applications
Matteo ManchiFull stack web developer
CEO at Impronta Advance
Twitter: @matteomanchi
AgendaFrom React to React NativeTechnologies behind RNMulti-platform compatibilityiOS and Android native modules
Let's start from thebeginning...
What is React.js?React is a JavaScript library for building user interfaces.
Just the UIOne-way data flowVirtual DOMFrom Facebook
Some keywordsComponent: Everything is a componentProps: some data passed to child componentState: some internal data of a componentJSX: XML-like syntax helps to define component'sstructureVirtual DOM: tree of custom objects representing a portof the DOM.
Component definitionimport React, {Component, PropTypes} from 'react';
class CountDown extends Component { static propTypes = { seconds: PropTypes.number.isRequired };
constructor(props) { super(props);
this.state = { seconds: props.seconds }; }
// ... }
Component definition - Pt.2class CountDown extends Component { // ... componentDidMount() { setInterval(() => this.setState({ seconds: this.state.seconds-1 }), 1000); }
render() { return ( <span>Time left: {this.state.seconds}</span> ); } } // Invoking < CountDown seconds="10" />
With or without you JSX// JSX render() { return ( <span>Time left: {this.state.seconds}</span> ); }
// plain js return React.createElement( "span", null, "Time left: ", this.state.seconds );
Let's talk back about mobileapplications
What are common troubles developing (multi-platform)mobile application?
Know howUse native APIsPerformance
React NativeA framework for building native apps using React.
Yeah, the same React.js of web developers
Learn once, write anywhere
What is React Native?A frameworkBinds JSX to iOS Cocoa Touch or Android UIAllow applications to run at near full speed
JSX to native UIExactly the same of React.js, but naming native components
// react-dom render() { return ( <div> <span>Time left: {this.state.seconds}</span> </div> ); }
// react-native render() { return ( <view> <text>Time left: {this.state.seconds}</text> </view> ); }
What do you mean withnear full speed?
Yes, like Titanium.
A lot of componentsActivityIndicatorIOSDatePickerIOSDrawerLayoutAndroidImageListViewMapViewModalNavigatorNavigatorIOSPickerIOSProgressBarAndroidProgressViewIOSPullToRefreshViewAndroidRefreshControlScrollView
SegmentedControlIOSSliderIOSSwitchTabBarIOSTabBarIOS.ItemTextTextInputToolbarAndroidTouchableHighlightTouchableNativeFeedbackTouchableOpacityTouchableWithoutFeedbackViewViewPagerAndroidWebView
A lot of APIsActionSheetIOSAlertAlertIOSAnimatedAppRegistryAppStateIOSAsyncStorageBackAndroidCameraRollDimensionsIntentAndroidInteractionManagerLayoutAnimationLinkingIOSNativeMethodsMixinNetInfo
PanResponderPixelRatioPushNotificationIOSStatusBarIOSStyleSheetToastAndroidVibrationIOS
Requirements forReact Native
Node.js 4.0 or newer.Xcode 7.0 or higher is required for iOS appsAndroid SDK + gradle + AVD/Genymotion for Androidapps
Getting Started$ npm install -g react-native-cli $ react-native init AwesomeProject $ cd AwesomeProject
// To run iOS app $ open ios/AwesomeProject.xcodeproj // To run Android app $ react-native run-android
Technologies behindReact Native
React, JSX and Virtual DOM :)Webpack loads all dependencies required by index.ios.jsand index.android.js and bundle them togetherES6 compatibility allows devs to use modern syntax andfeaturesNPM as module managerChrome Debugger as powerful debuggerFlow as type checker - optionally
All JavaScript's modulesEvery module there are not DOM-depending can be used inReact Native. Like a browser, there are some polyfills that
allow to use modules you have skill with.
FlexboxGeolocationNetwork (fetch, ajax, etc)Timers (timeout, interval, etc)
Inline CSS-like stylesCustom CSS implementation, easy to learn 'cause it's very
similar to browser's CSS.
With Flexbox.
In JavaScript.
https://facebook.github.io/react-native/docs/style.html
import {StyleSheet} from 'react-native';
const styles = StyleSheet.create({ base: { width: 38, height: 38, }, background: { backgroundColor: LIGHT_GRAY, }, active: { borderWidth: 4/2, borderColor: '#00ff00', }, });
<View style={[styles.base, styles.background]} />
What about multi-platforms?
React Native actually supports iOS and Android. Itprovides a lot of components and APIs ready to use in both
platforms.
A lot of componentsActivityIndicatorIOSDatePickerIOSDrawerLayoutAndroidImageListViewMapViewModalNavigatorNavigatorIOSPickerIOSProgressBarAndroidProgressViewIOSPullToRefreshViewAndroidRefreshControlScrollView
SegmentedControlIOSSliderIOSSwitchTabBarIOSTabBarIOS.ItemTextTextInputToolbarAndroidTouchableHighlightTouchableNativeFeedbackTouchableOpacityTouchableWithoutFeedbackViewViewPagerAndroidWebView
Native ModulesReact Native is madly growing up! Each release (almostonce per month) adds new features for both platforms
thanks to over 500 contributors.
Despite the big community around the project, can happenthat the native view you're looking for isn't supported bythe framework. In this case you have to wait for someoneelse, or make your native module (or binding native API)
iOS Module - Pt. 1// ShareManager.h #import < UIKit/UIKit.h > #import "RCTBridgeModule.h"
@interface RNShare : NSObject < RCTBridgeModule >
@end
iOS Module - Pt. 2// ShareManager.m @implementation ShareManager RCT_EXPORT_MODULE(); RCT_EXPORT_METHOD(share:(NSString *)text url:(NSString *)url) { NSURL *cardUrl = [NSURL URLWithString:url]; NSArray *itemsToShare = @[text, url, cardUrl]; UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:itemsToShare applicationActivities:nil];
UIViewController *root = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; [root presentViewController:activityVC animated:YES completion:nil]; } @end
iOS Module - Pt. 3var ShareManager = require('react-native').NativeModules.ShareManager; ShareManager.share('Hi from RomaJS!', 'http://www.romajs.org');
http://facebook.github.io/react-native/docs/native-modules-ios.html
Android Module - Pt. 1// ShareModule.java // package + imports public class ShareModule extends ReactContextBaseJavaModule { // ... public ShareModule(ReactApplicationContext reactContext) { super(reactContext); this.reactContext = reactContext; } @Override public String getName() { return "ShareManager"; }
// continue }
Android Module - Pt. 2// ShareModule.java public class ShareModule extends ReactContextBaseJavaModule { // ... @ReactMethod public void share(String text, String url) { Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); sharingIntent.setType("text/plain"); sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, text); sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, url);
Intent chooser = Intent.createChooser(sharingIntent, "Share"); chooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.reactContext.startActivity(chooser); } }
Android Module - Pt. 3// SharePackage.java // package + imports public class SharePackage implements ReactPackage { @Override public List< NativeModule > createNativeModules(ReactApplicationContext reactContext) { List< NativeModule > modules = new ArrayList<>(); modules.add(new ShareModule(reactContext)); return modules; }
// ... }
Android Module - Pt. 4// MainActivity.java
// ... mReactInstanceManager = ReactInstanceManager.builder() .setApplication(getApplication()) .setBundleAssetName("index.android.bundle") .setJSMainModuleName("index.android") .addPackage(new MainReactPackage()) .addPackage(new SharePackage()) .setUseDeveloperSupport(BuildConfig.DEBUG) .setInitialLifecycleState(LifecycleState.RESUMED) .build(); // ...
Android Module - Pt. 5var ShareManager = require('react-native').NativeModules.ShareManager; ShareManager.share('Hi from RomaJS!', 'http://www.romajs.org');
http://facebook.github.io/react-native/docs/native-modules-android.html
Different platform, different behavior
Take some actions depending to platform
Method 1: if/elseimport {Platform} from 'react-native';
const styles = StyleSheet.create({ myView: { backgroundColor: Platform.OS === 'ios' ? 'red' : 'lime' } });
Method 2: file extensionby webpack-based packager
// MyStyle.ios.js export default const styles = StyleSheet.create({ myView: { backgroundColor: 'red' } });
// MyStyle.android.js export default const styles = StyleSheet.create({ myView: { backgroundColor: 'lime' } });
Woah! Woah!
Questions?
Native HatersWhat about competitors?
Cordova/PhonegapIonicXamarinTitanium
Thank you