React Native

It's like ReactJS, but completely different!

How it works

Magic!

It looks like reactJS...

              class Foo extends React.Component {
                render() {
                  return (
                    <a href="//hooli.xyz">
                      <p>some text</p>
                    </a>
                  );
                }
              }
            

Not entirely...

class FooNative extends React.Component { _handlePress() { const platformMethod = Platform.OS === 'ios' ? LinkingIOS : IntentAndroid; platformMethod.openURL('https://hooli.xyz'); } render(){ return ( <TouchableHighlight onPress={this._handlePress}> <Text>some text</Text> </TouchableHighlight> ); } }

HTML Components, Native equivalent

  • p → Text
  • input → TextInput
  • checkbox → Switch
  • div → View
  • button →
    • TouchableHighlight
    • TouchableWithoutFeedback
    • TouchableNativeFeedback
    • TouchableOpacity
  • a → ¯\_(ツ)_/¯

Better HTML Components!

  • ListView
  • MapView
  • Navigator
  • Picker
  • ProgressBars

And more from the community!

Building with react-native


              import React from 'react-native';
              const { Image, Text, View, AppRegistry } = React;

              class MyApp extends React.Component{
                render() {
                  return (
                    <View style={styles.row}>
                      <Image source={{uri: 'http://www.feistees.com/wp-content/uploads/2014/05/squpd.jpg'}} style={styles.image} />
                      <View style={styles.text}>
                        <Text style={styles.title}>React Native </Text>
                        <Text style={styles.subtitle}>Build high quality mobile apps using React </Text>
                      </View>
                    </View>
                  );
                }
              });
              AppRegistry.registerComponent('Pied_Piper', () => MyApp);
            

Run it!


              react-native run-android    # (or through XCode for iOS)
            

Logs?


              adb logcat | grep ReactNative
              adb logcat *:S ReactNative:V ReactNativeJS:V  # from react-native docs
            

iOS logs are done through XCode

So,

How should we be using react-native?

Navigation

  1. <Navigator />
  2. react-native-router-flux

Navigator - Built into React-Native


              <Navigator
                  initialRoute={Routes.Login()}
                  renderScene={this.renderScene}
                  navigationBar={
                    <Navigator.NavigationBar
                        style={styles.navbar}
                        routeMapper={RouteMapper} />
                  }
              />
            

react-native-router-flux


              <Router navigationBarStyle={styles.navbar}>
                  <Schema name="default" sceneConfig={Navigator.SceneConfigs.FloatFromRight}
                      renderTitle={() => <NavbarTitle />} />
                  <Schema name="tab" type="switch" />
                  <Route name="main" type="replace" schema="default">
                      <Router footer={TabBar} tabBarStyle={styles.tabbar}>
                          <Route name="tab1" component={Tab1} schema="tab" icon={TabIcon} />
                          <Route name="tab2" component={Tab2} schema="tab" icon={TabIcon} />
                          <Route name="tab3" component={Tab3} schema="tab" icon={TabIcon} />
                      </Router>
                  </Route>
              </Router>
            

Native Code

Has to be done more often than you would think!

MyNativeModule.java
              @Override
              public String getName() {
                return "ThisModule";
              }
              @ReactMethod
              public void doCoolStuff() {
                System.out.print("Shw");
                for(int i=1; i<999; i++) {
                  System.out.print("a");
                 }
                System.out.println("g");
              }
            
MyNativePackage.java
              @Override
              public List<NativeModule> createNativeModules(
                                          ReactApplicationContext reactContext) {
                List<NativeModule> modules = new ArrayList<>();
                modules.add(new MyNativeModule(reactContext));
                return modules;
              }
            
MainActivity.java
              @Override
              protected List<ReactPackage> getPackages() {
                  return Arrays.<ReactPackage>asList(
                      new MainReactPackage(),
                      new MyNativePackage()
                  );
              }
            

              import { NativeModules } from 'react-native';
              NativeModules.ThisModule.doCoolStuff();
            
  • Native
  • Limitless
  • Asyncronous by default
  • Support for callbacks and promices
  • ReactMethods must be void - They cannot return
  • Written twice for both platforms

Styling

How are styles handled?


              const styles = StyleSheet.create({
                  dafont: {
                      backgroundColor: '#FF7F00',
                  },
              });
            

              <Text style={styles.dafont}>This Guy!</Text>
            

Layout

Custom implementation of Flexbox

  • Not all of flexbox is supported
  • API is not the same as CSS

Global Styles?

No! (╯°□°)╯︵ ┻━┻

  • Not necessary
  • Not easy:
    • Stylesheet is immutable, and arbitrary
    • Merging stylesheets isnt easy
    • Constant refining of stylesheets
  • You don't need to!
    • Unlikely
    • Defeats the point of components

If you have to do global styles...


              export function extendStylesheet(stylesheet) {
                  return StyleSheet.create(_.merge(globalStyles, stylesheet));
              }
            

Modules to the rescue!


              npm install react-native-extended-stylesheet --save
            

              EStyleSheet.build({
                  textColor: '#FF7F00'  // pass variables for styling
              });
            

              const styles = EStyleSheet.create({
                  column: {
                      width: '10%'  // percentage of screen width
                  },
                  text: {
                      color: '$textColor',  // use variable $textColor
                      fontSize: '3rem'  // use relative unit - CSS3 rem
                  }
              });
            

Variables and Styles

  1. Immutable.js
  2. Const exports

              export default Map({
                FONT_COLOUR: '#FF7F00',
                FOOTER_HEIGHT: 50
              });
            

              export const FONT_COLOUR = '#FF7F00';
              export const FOOTER_HEIGHT = 50;
            

              const styles = StyleSheet.create({
                  darkFont: {
                      backgroundColor: GlobalStyles.get('FONT_COLOUR'),
                  },
              });
            
So, now the tricky bit...

Tests!

React Native Components

  • react-native-mock
    • Doesn't actually render a component, just null instead
    • Wait... Is this actually a terrible idea? I don't know. Maybe.
    • But, does it work? Yes, rather well actually
test-helper.js
              require('react-native-mock/mock');
            

React Native APIs

  • dismissKeyboard
  • Platform
  • resolveAssetSource
test-helper.js
              mockery.registerMock('react-native-router-flux', require(MOCKS_DIR + '/react-native-router-flux'));
            

Testing Tools

  • Mocha etc...
  • Mockery
  • Enzyme + JSDOM

React Native

vs

Full Native

vs

Cordova

Is React-Native production ready?

No, Not really.

  • Is it native? Yes!
  • Is it fast? Yes!
  • Does it beat cordova + React.JS? God Yes!
  • But...
  • Does it fully support iOS and Android? No
  • Is it well documented? Not even close!
  • Is it easy to test? ┻━┻ ︵ヽ(`Д´)ノ︵ ┻━┻ (No)

What if we just go full native?

  • + Much Faster
  • + No API limitation
  • + Better Online Support
  • - Duel code base
  • - Completely different languages
  • - Updates require changes in multiple places
  • - Write everything from scratch
  • - I can actually build for iOS!

Benefits of react-native

If it's so incomplete, what's the point using it?

UI!

  • Shared UI code
  • Core basic functionality is done for you
  • Advanced functionality must be done natively
  • Mobile SDKs must be done natively
  • Everything else can share a codebase

The best solution

Hybrid Apps! (React-Native + Native Extensions)

So, What Next?

Find another solution?

Contribute!

  • react-native-mock
  • react-native-router-flux
  • enzyme

Tests for Native Code?

http://realorangeone.github.io/react-native-intro-dev-meeting - This Presentation

https://facebook.github.io/react-native - Source code

http://www.reactnative.com - Community

https://goo.gl/03PSv - React Conf 2016 Videos

Tah-da!