React Native

Cem Turan

Writing native Mobile Apps in Javascript

How to enable a web like workflow on native without sacrificing performance and feel.

for the working web developer

www.meetup.com

/GDG-Copenhagen/

Why

Native apps are fast, but

development is ...🐌

and 💰💰💰

We're hiring!

They are hiring!

EVERYONE IS HIRING!

Facebook shift to mobile was good in term of business, but so damaging in term of engineering velocity because of three things:

- Mark Zuckerberg

  1. iOS and Android are much harder to learn than web
  2. they need to staff more than 3x the number of engineers + all the overhead
  3. instead of shipping 2 times a day we could only once a month

- Christopher Chedeau (@vjeux)

... the same set of engineers should be able to build applications for whatever platform they choose, without needing to learn a fundamentally different set of technologies for each.

We call this approach "learn once, write anywhere"

- Tom Occhino

structure your organization around product teams

instead of

technical knowledge silos

building

build, install, launch app...

...navigate to screen, reproduce state

F5 on web

Slow Development cycle

Faster development iteration cycle

  • Live reload
  • Hot reload
  • Time travel
  • Teleportation

How do we get there?

well with React... (SPOILER ALERT!)

What

React

A JavaScript library for building user interfaces

Better abstraction for dealing with UI

Simple

+

Declarative

UI = f(data)

UI

Imperative

Declarative

var numbers = [1,2,3,4,5]
var doubled = []

for(var i = 0; i < numbers.length; i++) {
    var newNumber = numbers[i] * 2
    doubled.push(newNumber)
}
console.log(doubled) //=> [2,4,6,8,10]
var numbers = [1,2,3,4,5]
var doubled = numbers.map(n => n * 2)





console.log(doubled) //=> [2,4,6,8,10]
var loginText = document.querySelector(".login_text");
loginText.innerHTML = ( isLoggedIn 
    ? "Logged in as: " + model.name 
    : "Please log in"
);
var loginBtn = document.querySelector(".login_button");
loginBtn.style.visibility = ( isLoggedIn 
    ? "" 
    : "gone"
);

//View construction / HTML not included!!!
<View> //JSX syntax: Embedded DSL/Syntactic Sugar
    <Text> { 
      isLoggedIn 
      ? "Logged in as: " + model.name 
      : "Please log in"
    }</Text>

    { isLoggedIn
      ? <LoginButton />
      : null
    }
</View>

/

How  vs  What

Shout out to FP!

JSX

Simple

React has no:

Controllers

Models

Views

Templates

View Models

<Component />

Primitive

Essentially state machines

Encapsulated and Reusable, components makes code reuse, testing and separation of concerns a breeze.

Stateful

Stateless

class ChatApp extends React.Component{
  constructor(props){
    super(props)
    this.state = {
      friends: [],
      messages: []
    }
    // perform request for data
  }

  handleSubmit(message){
  //...
  }

  render(){ return
    <View>
      <FriendList 
       friends={this.state.friends}/>
      <MessageList 
       messages={this.state.messages}/>
      <MessageInput 
       handleSubmit={m => this.handleSubmit(m)}/>
    </View>
  }
}
let MessageList = (props) =>
  <View>
    <Text>Messages:</Text>
    {
      props.messages.map(message =>{
        return <MessageListItem
          key={message.id}
          message={message}
        />
      })
    }
  </View>
  
//Available in React but coming very soon
//to React Native

Pure function

class ChatApp extends React.Component{
  constructor(props){
    super(props)
    this.state = {
      friends: [],
      messages: []
    }
    // perform request for data
  }

  handleSubmit(message){
    this.setState({
      messages: messages.concat(message)
    })
  }

  render(){ return
    <View>
      <FriendList 
       friends={this.state.friends}/>
      <MessageList 
       messages={this.state.messages}/>
      <MessageInput 
       handleSubmit={m => this.handleSubmit(m)}/>
    </View>
  }
}
class ChatApp extends React.Component{
  constructor(props){
    super(props)
    this.state = {
      friends: [],
      messages: []
    }
    // perform request for data
  }

  handleSubmit(message){
    // setState / server call / dispatch action
  }

  render(){ return
    <View>
      <FriendList 
       friends={this.state.friends}/>
      <MessageList 
       messages={this.state.messages}/>
      <MessageInput 
       handleSubmit={m => this.handleSubmit(m)}/>
    </View>
  }
}

Props

State

React Data Flow

  • Passed in from parent
  • Immutable / read-only
  • can be defaulted and validated
  • can be defined via propTypes
  • Created within component
  • this.state to read
  • this.setState() to update
  • considered private

React Data Flow

unidirectional flow: props down, events up

architectures: flux, cyclejs, elm-architecture

React Native

  • Replaces the DOM renderer with iOS/Android renderer
  • Declared UI elements are native views!
  • Not HTML/JS/CSS in Web View ala. Phonegap/Cordova
  • Integrate with existing Native code

Basic building blocks

React Web React Native Android iOS
Block <div> <View> <ViewGroup> UIView
Inline <span> <Text> <TextView> TextView
Image <img> <Image> <ImageView> UIImageView

Native components

Platform Dependent (suffixed)

Platform independent

 

 

 

 

 

Touchable (behavioral) components

How

We conceptually push F5 and re-render!

Re-render everything?!

Declarative

Apple Watch?

What could possibly go wrong!?

Virtual DOM

  • When data changes, components are re-rendered.
  • Easy and intuitive to developers.

Efficient because on every update:

  1. React builds a virtual representation of the UI in memory, i.e. VDOM.
  2. Diffs it with the old one.
  3. Calculates the smallest set of changes to make to go from the current UI to the next one.
  4. All updates are batched and sent to the renderer.

Renderer

Two-threaded architecture

  • JS thread
  • UI/Main thread

 

 

Bridge ensures Async serialized communication.

 

 

Task queue of changes are transformed to Imperative native calls on the native side.

websocket

Styling & Layout

Layout

CSS: The good parts

Flexbox

Flexbox

<View style={styles.row}>
  <Image src={ /* ... */ } />
  <View style={styles.textContainer}>
    <Text style={styles.movieTitle} /* ... */ </Text>
    <Text style={styles.movieYear} /* ... */ </Text>
  </View>
</View>

var styles = {
  row: {
    backgroundColor: 'white',

    alignItems: 'center',
    flexDirection: 'row',

    padding: 6
  }
}

Learn flexbox.io

UI Manager

{
  margin: 20,
  borderBottonWidth: 2,
  flex: 1,
  alignContent: 'center'
}
{
  left: 120,
  top: 220,
  width: 60,
  height: 60
}

Flexbox

Coordinates

Native Modules

Integrating with existing app

Where

WEB

Native Mobile

Native Desktop

Terminal?

Hardware!?

import React, {Board, Led} from 'react-hardware';

const HIGH = 255, LOW = 0;

class FlashingLed extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 0,
      _timer: null,
    };
  }

  componentDidMount() {
    this.state._timer = setInterval(_ => (
      this.setState({value: this.state.value === HIGH ? LOW : HIGH})
    ), this.props.interval);
  }

  render() {
    return (
      <Led {...this.props} value={this.state.value} />
    );
  }
}
class Application extends React.Component {
  render() {
    return (
      <Board>
        <FlashingLed pin={9} />
        <FlashingLed pin={10} />
        <FlashingLed pin={11} />
        <FlashingLed pin={12} />
      </Board>
    );
  }
}

var PORT = '/dev/tty.usbmodem1411';
React.render(<Application />, PORT);

Summary

Why React (Native)?

  • Same paradigm across platforms
  • It's JavaScript (npm)
  • Sane layout system
  • Truly Native
  • Great backing and huge community

Community

HUGE!

reactiflux.slack.com 

join.reactiflux.com (Discord)

Ecosystem

React Devtools

Redux Devtools

React Native Playground

Microsoft Code Push

react.parts

Directory of React Native and React Web components and modules.

NPM

Pick your Language

Compile to JS

Clojurescript

Typescript

Kotlin

Dart

Elm

Questions?

Thanks!

Cem Turan

React Native

By Cem Turan

React Native

  • 1,015