React Native : Not as Horrible as You Think

React Native : Not as Horrible as You Think

Over the past year, we've been implementing a cross-platform chat application using React Native for Android and iOS, while trying to keep it as close to real React JS code as possible. In this talk, we'll help you avoid the pitfalls we ran across in cross-platform (and even cross-model) behavior, as well as sensible theming, navigation, and state management techniques.

Presented at ConFoo 2019:
https://confoo.ca/en/yul2019/session/react-native-not-as-horrible-as-you-think

Ac1a1d449af259bfb7191105db5212a2?s=128

Sunny Gleason

March 13, 2019
Tweet

Transcript

  1. Sunny Gleason ConFoo 2019 (Not as Horrible as you Think)

  2. whoami • Sunny Gleason
 @sunnygleason, sunnygleason 
 SunnyCloud, Boston MA

    • Application Development (Web & Mobile)
 Distributed Systems (Cloud)
 Security & Compliance • Prior Work • Independent developer/army of one…
  3. who-are-you? • Web Application Developers? • Mobile Application Developers? iOS?

    Android? • Full-stack? Backend? • Data Scientists? • React? React Native? • AngularJS? Vue.js? • Ember? Backbone? jQuery?
  4. Developing w/ React Native • What is React? • What

    is React Native? • Getting Started • Components, Properties, State, Lifecycle • Theming, Navigation & State • Cross-Platform & Devices
  5. Sample Chat Application

  6. Getting Started with React Native • See React Native -

    Getting Started • Prerequisites: node/npm • $ npm install -g react-native-cli • Install XCode and/or Android Studio • $ react-native run-ios • $ react-native run-android
  7. Creating an App • See React Native - Getting Started

    • $ react-native init AwesomeProject • Look at App.js for your application code • Look in android and ios folders for platform- specific code
  8. export default class App extends Component<Props> { constructor(props) { super(props);

    this.state = { count: 0 }; } incrementCount = () => (event) => { ... };
 render() { return ( <View style={styles.container}> <Text style={styles.welcome}>
 Button Presses: {this.state.count}
 </Text> <Button onPress={this.incrementCount()}
 title="Click Me" /> </View> ); } } const styles = StyleSheet.create({ ... }); React App
  9. React Component https://code.tutsplus.com/tutorials/stateful-vs-stateless-functional-components-in-react--cms-29541 <MyComponent title={“Hello World”} />

  10. export default class MyComponent extends Component<Props> { constructor(props) { super(props);

    this.state = { count: 0 }; } incrementCount = () => (event) => { let newState = {...this.state}; newState.count += 1; this.setState(() => { return newState; }); } render() { const styles = this.props.styles; const instructions = this.props.instructions; return ( <View style={styles.container}> <Text style={styles.welcome}>
 Button Presses: {this.state.count}
 </Text> <Button onPress={this.incrementCount()} title="Click Me" /> </View> ); } } React Component
  11. export default class App extends Component<Props> { constructor(props) { super(props);

    ... } incrementCount = () => (event) => { ... };
 render() { return ( <View style={styles.container}> <View style={styles.container}> <Text ... /> <Button ... /> </View>
 <View style={styles.container}> <Text ... /> <Button ... /> </View> </View> ); } } React App
  12. export default class App extends Component<Props> { constructor(props) { super(props);

    }
 render() { return ( <View style={styles.container}> <MyComponent />
 <MyComponent /> </View> ); } } React App
  13. export default class App extends Component<Props> { constructor(props) { super(props);

    this.state = { count: 0 }; } incrementCount = () => (event) => { let newState = {...this.state}; newState.count += 1; this.setState(() => { return newState; }); }; render() { return ( <View style={styles.container}> <MyComponent styles={styles} instructions={instructions} 
 count={this.state.count} 
 onPress={this.incrementCount()} /> <MyComponent styles={styles} instructions={instructions}
 count={this.state.count}
 onPress={this.incrementCount()} /> </View> ); } } React App
  14. React Component Lifecycle https://medium.com/@kartikagarwal01/react-component-lifecycle-old-vs-new-32757aee5850

  15. React Component Lifecycle https://medium.com/@kartikagarwal01/react-component-lifecycle-old-vs-new-32757aee5850

  16. How does it work? https://levelup.gitconnected.com/wait-what-happens-when-my-react-native-application-starts-an-in-depth-look-inside-react-native-5f306ef3250f

  17. How does it work? • Good news! • Near-native performance

    • Rough cross-platform compatibility out of the box • Debugging! • Not-so-Good news! • Tricky things like Layout, Network/Sleep/ Wake events, Device- specific and Component-specific issues will bite you • To fix them, need to dig through extra layer(s)
  18. Debugging

  19. React Native Sample App https://www.pubnub.com/tutorials/chatengine/react-native-android/how-to-build-a-chat-app/ https://www.pubnub.com/tutorials/chatengine/react-native-ios/how-to-build-a-chat-app/ https://github.com/sunnygleason/chatengine-react-native-sample/

  20. Navigation • Navigation is a slight pain • Obviously, URL

    is not available like a web app • Routing libraries are/were still competing • We used the 
 react-navigation library, SwitchNavigator https://github.com/sunnygleason/chatengine-react-native-sample/blob/master/App.js
  21. Navigation • Navigation can get tricky when promises are involved…

    • react-navigation uses navigation.navigate to change the current view https://github.com/sunnygleason/chatengine-react-native-sample/blob/master/lib/ce-view-chatlist.js
  22. Theming • StyleSheet is not awesome • There is a

    lot of maintenance & plumbing into components • It’s not clear how to organize https://github.com/sunnygleason/chatengine-react-native-sample/blob/master/lib/ce-theme-style.js
  23. Theming • Theming is not just “Styles”, requires deep integration

    • Choose a component library that has built-in theming • Or, use similar patterns to these… https://github.com/xotahal/react-native-material-ui https://callstack.github.io/react-native-paper/
  24. State • State management & updates are tricky • You

    can do a lot with props and state • Relationships can get complicated… https://github.com/sunnygleason/chatengine-react-native-sample/blob/master/lib/ce-model-updateable.js https://github.com/sunnygleason/chatengine-react-native-sample/blob/master/lib/ce-model-chat-messagelist.js
  25. State • Chat room • Message View • Message Entry

    • Typing Indicator • Inbound messages • User List • Connected/Disconnected https://github.com/sunnygleason/chatengine-react-native-sample/blob/master/lib/ce-model-chat-chatroom.js
  26. Platform-Specific • Android App Bar • iOS navigation • Android

    text components/underline • iOS SafeAreaView • Keyboard-aware layouts https://github.com/sunnygleason/chatengine-react-native-sample/blob/master/lib/ex-screen-application.js
  27. Device-Specific • iPhone X “notch” • iPhone X bottom padding

    & SafeAreaView https://github.com/sunnygleason/chatengine-react-native-sample/blob/master/lib/ex-screen-application.js
  28. React Native Sample App https://www.pubnub.com/tutorials/chatengine/react-native-android/how-to-build-a-chat-app/ https://www.pubnub.com/tutorials/chatengine/react-native-ios/how-to-build-a-chat-app/ https://github.com/sunnygleason/chatengine-react-native-sample/

  29. Conclusions • React Native & React significantly accelerate mobile app

    development • But, they come with some pitfalls to be aware of • Hopefully this helps you avoid them • Let me know if you run into any issues! • Thank you for coming!