Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Lessons from a year of building apps with React Native

105 views

Published on

Lessons from a year of building apps with React Native

Published in: Technology
  • Be the first to comment

Lessons from a year of building apps with React Native

  1. 1. React Native Lessons from a year of building apps with Ryan Boland
  2. 2. ryanboland.com // tanookilabs.com ryan@tanookilabs.com @bolandrm (github, twitter) I’m Ryan Boland Web Developer @ Tanooki Labs
  3. 3. Slides • ??
  4. 4. Goals • Brief introduction to React Native itself • Short demo on running a React Native app and the development loop • Decide whether React Native would be a good fit for your project • Sensible blueprint for starting your own React Native app
  5. 5. My experience thus far • Viewer + organizer for financial research articles • Ca-Ching! iOS + Android
  6. 6. Getting up to speed on React Native No real prerequisites for getting started, but having someone on the team who is familiar with Xcode and/or android studio is a huge help
  7. 7. React Native is a framework that allows you to build native applications with JavaScript and React import React, { Component } from 'react'; import { Image, ScrollView, Text } from 'react-native'; class ScrollingImageWithText extends Component { render() { return ( <ScrollView> <Image source={{uri: 'https://i.chzbgr.com/full/7345954048/h7E2C65F9/'}} style={{width: 320, height:180}} /> <Text> On iOS, a React Native ScrollView uses a native UIScrollView. On Android, it uses a native ScrollView. </Text> </ScrollView> ); } } https://facebook.github.io/react-native/
  8. 8. React Native is real native
  9. 9. Directory structure
  10. 10. Directory structure
  11. 11. Directory structure
  12. 12. Directory structure
  13. 13. Directory structure
  14. 14. Layout + Styling import React, { Component } from 'react'; import { AppRegistry, View } from 'react-native'; export default class FlexDirectionBasics extends Component { render() { return ( <View style={{flex: 1, flexDirection: 'row'}}> <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} /> <View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} /> <View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} /> </View> ); } };
  15. 15. Layout + Styling import React, { Component } from 'react'; import { AppRegistry, View } from 'react-native'; export default class FlexDirectionBasics extends Component { render() { return ( <View style={{flex: 1, flexDirection: 'row'}}> <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} /> <View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} /> <View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} /> </View> ); } };
  16. 16. Layout + Styling import React, { Component } from 'react'; import { AppRegistry, View } from 'react-native'; export default class FlexDirectionBasics extends Component { render() { return ( <View style={{flex: 1, flexDirection: 'row'}}> <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} /> <View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} /> <View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} /> </View> ); } };
  17. 17. Built-in components • View, Text, Image, TextInput, ScrollView, StyleSheet • Button, Picker, Slider, Switch • FlatList, SectionList • ActivityIndicator, Alert, CameraRoll, Modal, etc…
  18. 18. Android / iOS specific code Example: platform specific button. • Write Android implementation in Button.android.js • Write iOS implementation in Button.ios.js import Button from 'Button'; ...
  19. 19. Demo!
  20. 20. Why choose React Native?
  21. 21. Fast Development • Quick development loop - refresh the app immediately in most cases (no waiting for compile) • The majority of your app’s code will be reused between Android and iOS • Take advantage of large JavaScript package ecosystem
  22. 22. Your team can get up to speed quickly • Much of the work can be done by folks with little native development experience • Framework is made of simple, easy to use components
  23. 23. No lock-in • You can use React Native as much or as little as you’d like (maybe you just want to use it for settings or form pages) • If you have a major component in your app, you can write it in native code • If the team outgrows react native, it can be phased out over time Discord article -> https://blog.discordapp.com/why-discord-is-sticking-with-react-native-ccc34be0d427
  24. 24. Downsides • Many different technologies being used simultaneously • The build process is more complicated • Updates can be painful (both React Native and ios/android updates) • Android support is lagging a bit
  25. 25. Spinning up your first React Native app
  26. 26. There are a lot of decisions!
  27. 27. Frameworks / boilerplates
  28. 28. Navigation
  29. 29. Organizing JS
  30. 30. MobX for state!
  31. 31. Airbnb on Redux “…Redux is notorious for its boilerplate and has a relatively difficult learning curve. We provided generators for some common templates but it was still one of the most challenging pieces and source of confusion while working with React Native.” https://medium.com/airbnb-engineering/react-native-at-airbnb-the-technology- dafd0b43838
  32. 32. Organizing JS
  33. 33. Component “pods” // components/index.js and components/Button/index.js // allow for the following: import Button from ‘components’
  34. 34. Testing
  35. 35. import React from 'react' import Button from 'app/components/Button' import {shallow} from 'enzyme' describe('Button component', () => { it('is unclickable, renders with lower opacity with disabled prop', () => { const wrapper = shallow( <Button disabled text="Disabled" /> ) expect(wrapper).toMatchSnapshot() }) }) Component Snapshot testing Button.test.js
  36. 36. import React from 'react' import Button from 'app/components/Button' import {shallow} from 'enzyme' describe('Button component', () => { it('is unclickable, renders with lower opacity with disabled prop', () => { const wrapper = shallow( <Button disabled text="Disabled" /> ) expect(wrapper).toMatchSnapshot() }) }) Component Snapshot testing Button.test.js
  37. 37. import React from 'react' import Button from 'app/components/Button' import {shallow} from 'enzyme' describe('Button component', () => { it('is unclickable, renders with lower opacity with disabled prop', () => { const wrapper = shallow( <Button disabled text="Disabled" /> ) expect(wrapper).toMatchSnapshot() }) }) Component Snapshot testing Button.test.js
  38. 38. // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Button component is unclickable, renders with lower opacity with disabled prop 1`] = ` <TouchableOpacity activeOpacity={0.5} disabled={true} style={ Array [ Object { "width": "100%", }, undefined, ] } > <Component style={ Array [ Object { "backgroundColor": "#49718C", "borderRadius": 2, "padding": 12, }, Object { "opacity": 0.6, }, Object {}, ] } > <inject-Text-with-settings style={ Array [ Object { "color": "#FFFFFF", "fontFamily": "SourceSansPro-SemiBold", "textAlign": "center", }, undefined, ] } > Disabled </inject-Text-with-settings> </Component> </TouchableOpacity> `; Button.test.js.snap “Golden master testing”
  39. 39. Sharing your App Purpose Server Distributed via Debug Local development Staging n/a Internal Internal / stakeholder testing Staging Fabric Beta, hockey app, etc Beta/QA Final approval / early adopter testing Production Fabric Beta, hockey app, etc Release Release to public Production App Store
  40. 40. App Versions App identifier -> com.tanookilabs.street-cuts.internal react-native-device-info allows us to pull out the app version from the app identifier: import DeviceInfo from 'react-native-device-info' export const isRelease = DeviceInfo.getBundleId().split('.').includes('release') export const isBeta = DeviceInfo.getBundleId().split('.').includes('beta') export const isInternal = DeviceInfo.getBundleId().split('.').includes('internal') export const isDebug = DeviceInfo.getBundleId().split('.').includes('debug') Use react-native-schemes-manager when creating non- standard versions (e.g. internal/beta)
  41. 41. Continuous Integration • Tests and linting are run for all pull requests • Each push to master runs tests, linting, and builds iOS and android internal version of the app • Beta and release versions of the apps can be built on demand
  42. 42. Shipping to the app stores
  43. 43. Long Term Maintenance Update regularly!
  44. 44. https://github.com/ncuillery/rn-diff/
  45. 45. React Native is a game changer for both developers and their clients!
  46. 46. Further exploration • Using CodePush to update production applications without submitting through the app store processes • Using TypeScript or Flow to avoid runtime errors
  47. 47. Thanks! Questions? ryanboland.com // tanookilabs.com ryan@tanookilabs.com @bolandrm (github, twitter) Tanooki Labs Slides ->

×