Share
Embed
React Native: Native mobile development with JavaScript
ChernihivJS #5
23.06.2016
Roman Liutikov
June 23, 2016
Transcript
39 slides
-
Native mobile development with JavaScript PhoneGap — WebView + native
plugins Tabris.js — native UI NativeScript — native UI, Angular 2, TypeScript React Native — native UI, React.js -
React Native • Released in 2015 • Open source •
Maintained by Facebook and community • Cross-platform mobile development (iOS, Android, UWP) • Based on React • New release every 2 weeks -
Benefits for developers • Use language that you already know
— JavaScript • Use UI library that you already know — React • Develop cross-platform applications • Interactive development, because JavaScript is dynamic language • Send instant updates to your users, no need to submit to App Store -
How it works • Bridge between native code and JavaScript
• 2 main threads ◦ Main thread — create and position views ◦ JavaScript thread — your code • Dispatch queues (more efficient at executing tasks) ◦ Shadow queue — layout calculation ◦ + one queue for every native module -
Getting started • React Native CLI npm i -g react-native-cli
• MacBook, Xcode, iOS device/simulator, Apple Developer Program ($100) • Java, Android SDK, Android device/simulator • Chrome’s DevTools • Integrated Inspector • React Native CodePush -
There’s no... • No HTML • No CSS • No
DOM APIs • No Web APIs -
Views / JSX / Native views <View> <Text style={styles.text}>Hello!</Text> <TextInput
value={val} onChangeText={handleChange} /> <TouchableHighlight onPress={handlePress}> <Text>Submit</Text> </TouchableHighlight> </View> -
Styles / Polyfilled subset of CSS Flexbox var styles =
StyleSheet.create({ container: { flex: 1, alignItems: 'center' } }); var styles = StyleSheet.create({ button: { backgroundColor: 'blue', borderColor: 'red', borderWidth: StyleSheet.hairlineWidth } }); -
UI Events • No generic click / onchange events •
Use TouchableHighlight for buttons and “links” • Use onStartShouldSetResponder to capture touch events on View -
Polyfilled Web APIs • Geolocation API • Fetch API •
No localStorage, use AsyncStorage -
100% shared code is not possible • Platform-specific components •
Different Design Guidelines • Different behaviour • Different interactions -
What can be shared? • Content UI (forms, news feed,
...) • Domain logic (data flow) • Data fetching -
How to develop cross-platform app? • Separate domain logic and
data fetching from UI • Use Flux / Redux • Use cross-platform native modules • Use ios and android suffixes in filenames (button.ios.js, button.android.js) -
Native Modules • TabBarIOS, ToolbarAndroid, ViewPagerAndroid, … • Do not
use pure JavaScript module if there’s a native one • Native modules works faster and they can do more • Use RNPM to install native modules • If there’s something missing you can always expose it to JavaScript -
Declare a class with RCTBridgeModule protocol #import "RCTBridgeModule.h" @interface CalendarManager
: NSObject <RCTBridgeModule> @end -
Implement it @implementation CalendarManager RCT_EXPORT_MODULE(); RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location) {
RCTLogInfo(@"Pretending to create an event %@ at %@", name, location); } @end -
Use in JavaScript import { NativeModules } from 'react-native'; var
CalendarManager = NativeModules.CalendarManager; CalendarManager.addEvent( 'Birthday Party', '4 Privet Drive, Surrey'); -
Graphics • Do not use scaled down high-res images, it
slows down scrolling perf • When updated image can blink due to slow processing • Use SVG is possible (ReactNativeART) -
Slow initial rendering in ListView • Specify reasonable initialListSize •
Same for pageSize <ListView initialListSize={15} pageSize={15} dataSource={dataSource} renderRow={renderRow} /> -
Frequent re-rendering Use setNativeProps to set data directly on native
component this.refs.input.setNativeProps({ text }); -
Avoid expensive work during animations Use InteractionManager to schedule expensive
work after animations / interactions InteractionManager.runAfterInteractions(() => { // ...long-running synchronous task... }); -
Animations Use LayoutAnimation for simple and uncontrolled animations. Layout animation
happens on the main thread on next layout. componentWillUpdate() { LayoutAnimation.configureNext(config); } -
Animated this.state = { opacity: new Animated.Value(0) }; Animated.timing(this.state.opacity, {
toValue: 1 }).start(); <Animated.View style={{ opacity }} /> -
Animated • Use it for complex and controlled animations •
Controlled from JS thread • Imperative API -
Navigator <Navigator initialRoute={{ title: 'Home', index: 0 }} renderScene={(route, navigator)
=> <Layout route={route} onNext={() => navigator.push({ title: 'Next', index: 1 })} /> } /> -
Navigator • No nested routes • Navigator maintains a stack
of routes • Runs transition animation between screens • Imperative API • Take a look at NavigationExperimental • When starting a new project think about how you would implement navigation -
Development • Remember that application runs slower in Development mode
• Don’t forget to enable hot-reloading • Debug in Chrome’s DevTools • Use integrated Inspector to find components, inspect styles and layout -
Tests • Separate domain logic domain from UI so unit
tests will become easier • Enzyme and Mocha for unit tests • Integration tests are more complex -
Reading list • Bridging in React Native • Dive into
React Native performance • React Native Integration Tests • Performance Limitations of React Native and How to Overcome Them • Using React Native: One Year Later • Routing and Navigation in React Native • js.coach/react-native • facebook.github.io/react-native • jondot/awesome-react-native • react-native-code-push Questions? @roman01la