Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

Sunny Gleason

March 13, 2019
Tweet

More Decks by Sunny Gleason

Other Decks in Technology

Transcript

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

    • Application Development (Web & Mobile)
 Distributed Systems (Cloud)
 Security & Compliance • Prior Work • Independent developer/army of one…
  2. 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?
  3. Developing w/ React Native • What is React? • What

    is React Native? • Getting Started • Components, Properties, State, Lifecycle • Theming, Navigation & State • Cross-Platform & Devices
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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
  9. export default class App extends Component<Props> { constructor(props) { super(props);

    }
 render() { return ( <View style={styles.container}> <MyComponent />
 <MyComponent /> </View> ); } } React App
  10. 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
  11. 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)
  12. 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
  13. 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
  14. 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
  15. 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/
  16. 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
  17. 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
  18. 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
  19. 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
  20. 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!