React Native Introduction

React Native is not really a hybrid app framework

write once, run anywhere
learn once, write anywhere 

Let's compare it to hybrid apps

React Native Hybrid 
Shared and platform exclusive code All code shared
Javascript + JSX Javascript + HTML + CSS
Live and hot reload  Live and hot reload
No WebView WebView
Native performance Browser performance
Relatively new Lot's of mature plugins

No WebView? Is Javascript compiled to binary then?

  • Javascript is run in a separate thread, using Javascript engine, named JavaScriptCore, which also powers Safari

 

  • While debugging with Chrome, the code is actually run within Chrome's V8 engine and communicates with app through web sockets

Not at all!

Here's the whole picture 

Three parts of React Native

  1. React Native - Native Side
  2. React Native - Javascript Side
  3. React Native - Bridge

Basic UI components

View The most fundamental component for building a UI.
Text A component for displaying text.
Image A component for displaying images.
TextInput A component for inputting text into the app via a keyboard.
ScrollView ​Provides a scrolling container that can host multiple components and views.
Button ​A basic button component for handling touches that should render nicely on any platform.
Picker Renders the native picker component on iOS and Android.
Slider A component used to select a single value from a range of values.
Switch Renders a boolean input.
FlatList A component for rendering performant scrollable lists.
SectionList Like FlatList, but for sectioned lists.

Platform specific components

  • DatePickerIOS
  • AlertIOS
  • TabBarIOS
  • ImagePickerIOS
  • PushNotificationIOS
  • BackHandler
  • DatePickerAndroid
  • TimePickerAndroid
  • PermissionsAndroid
  • ToastAndroid
  • ViewPagerAndroid
  • ToolbarAndroid

Other shared components and classes

  • StatusBar
  • Modal
  • StyleSheet
  • KeyboardAvoidingView
  • WebView

Let's take a look at the code

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { AppRegistry, Text, TouchableOpacity } from 'react-native'

import { Metrics, Colors, Fonts } from '../Themes'

const styles = {
  text: {
    ...Fonts.style.h5,
    color: Colors.snow,
    marginVertical: Metrics.baseMargin
  }
}

export class Button extends Component {
  static propTypes = {
    text: PropTypes.string,
    onPress: PropTypes.func
  }

  render () {
    return (
      <TouchableOpacity onPress={this.props.onPress}>
        <Text style={styles.text}>{this.props.text}</Text>
      </TouchableOpacity>
    )
  }
}

AppRegistry.registerComponent('ButtonApp', () => Button)

React Native navigation

Currently suggested solution is to use react-community/react-navigation​ 

First screen

import React from 'react';
import {
  AppRegistry,
  Text,
} from 'react-native';
import { StackNavigator } from 'react-navigation';

class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Welcome',
  };
  render() {
    return <Text>Hello, Navigation!</Text>;
  }
}

const SimpleApp = StackNavigator({
  Home: { screen: HomeScreen },
});

AppRegistry.registerComponent('SimpleApp', () => SimpleApp);

Here's the effect

Android

iOS

Second View

class ChatScreen extends React.Component {
  static navigationOptions = {
    title: 'Chat with Lucy',
  };
  render() {
    return (
      <View>
        <Text>Chat with Lucy</Text>
      </View>
    );
  }
}


class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Welcome',
  };
  render() {
    const { navigate } = this.props.navigation;
    return (
      <View>
        <Text>Hello, Chat App!</Text>
        <Button
          onPress={() => navigate('Chat')}
          title="Chat with Lucy"
        />
      </View>
    );
  }
}
const SimpleApp = StackNavigator({
  Home: { screen: HomeScreen },
  Chat: { screen: ChatScreen },
});

Here's the effect

Android

iOS

Testing

  • Jest
  • Enzyme (doesn't support mounting)
  • Tree snapshots

Tree snapshots

import renderer from 'react-test-renderer';

test('Link renders correctly', () => {
  const tree = renderer.create(
    <Link page="http://www.facebook.com">
      Facebook
    </Link>
  ).toJSON();
  expect(tree).toMatchSnapshot();
});
exports[`Link renders correctly 1`] = `
<a
  className="normal"
  href="http://www.facebook.com"
  onMouseEnter={[Function bound _onMouseEnter]}
  onMouseLeave={[Function bound _onMouseLeave]}>
  Facebook
</a>
`;

There's a really nice boilerplate

Ignite CLI

Ignite CLI

$ npm install -g ignite-cli
$ ignite new PizzaApp
$ cd PizzaApp
$ ignite add maps
$ ignite add vector-icons
$ ignite generate screen PizzaLocationList
$ ignite generate component PizzaLocation
$ ignite generate map StoreLocator
$ ignite add i18n

Run the app

$ react-native run-ios
$ react-native run-android

React Native Introduction

By Patryk Ziemkowski

React Native Introduction

  • 640