React JS + React Native

React Fundamentals

  • JSX
  • Hello World
  • Virtual DOM

JSX

  • Not a template language (ie. handlebars, spacebars etc..)
  • Alternate JS syntax
  • Does a lot of string conversion
<div id="greeting-container" className="container">
  <Greeting name="World"/>
</div>

Becomes: 

React.createElement("div",
  {
    id: "greeting-container",
    className: "container"
  },
  React.createElement(Greeting, {name: "World"})
)

Hello World

<body>
  <div id="content"></div>

  <script type="text/jsx">

    var CounterBox = React.createClass({
      render: function () {
        return (
          <h1>Hello World</h1>
          )
      }
    });

    React.render(
      <CounterBox />,
      document.getElementById('content')
    );
  </script>
</body>

-Local example-

Virtual DOM

All React elements are in-memory virtual representations of DOM elements.  React uses this.state to register changes on certain elements.  It then runs a diff between Virtual DOM elements, then pushes the changes to the DOM.

React Syntax

  • React.createClass
  • getInitialState
  • componentDidMount
  • componentWillUnmount
  • setState
  • React.renderComponent
  • props

React.createClass

var TimerExample = React.createClass({

    // Custom functions as well as basic components here

})

Used to create a custom component (similar to an Angular directive) that is used to render elements, as well as contain logic, to the page.

getInitialState

var TimerExample = React.createClass({

    getInitialState: function(){

        return { elapsed: 0 };

    }

})

Called before the render function.  The object that is returned is assigned to this.state.

componentDidMount

var TimerExample = React.createClass({

    // Previous functions

    componentDidMount: function(){

        this.timer = setInterval(this.tick, 50);

    }

})

Called after the component has been rendered to the page.

componentWillunmount

var TimerExample = React.createClass({

    componentWillUnmount: function(){

        clearInterval(this.timer);

    }

})

Called before the destroy functions get run on the component.

setState

this.setState({elapsed: new Date() - this.props.start});

Used to keep track of variables/objects that are closely coupled with React display elements.  Each call forces a component refresh. 

render

var TimerExample = React.createClass({

    // Previous functions

    render: function() {

        // Although we return an entire <p> element, react will smartly update
        // only the changed parts, which contain the seconds variable.

        return <p>This example was started <b>{seconds} seconds</b> ago.</p>;
    }    

})

Called to render the component to the page.

React.renderComponent

React.renderComponent(

    <TimerExample start={Date.now()} />,
    document.body

);

Used to initiate the rendering sequence for an element, as well as specifying where the element is getting injected.

props

<TimerExample start={Date.now()} count='1000'/>

Variables passed to the React component are set on the props object that each React component has.

-Timer example-

React's opinion of CSS

  • “Begone, foul dwimmerlaik, lord of carrion! Leave the dead in peace!" - JRR
  • Translation: Facebook strongly dislikes CSS 
  • https://facebook.github.io/react-native/docs/style.html#content

CSS (React Native)

 

  • Declared as JS variables
  • Set as inline by default
var styles = StyleSheet.create({
  container: {
    width: 38,
    height: 38,
  },
  title: {
    borderWidth: 2,
    borderColor: '#00ff00',
  },
  description: {
    fontSize: 18,
    margin: 5,
    color: '#656565'
  }
});

Ways of Applying CSS

  • Regular inline
  • Combining elements as an array
  • Adding styles conditionally
<View style={styles.background} />

<View style={[styles.base, styles.background]} />

<View style={[styles.base, this.state.active && styles.active]} />

Inheriting Styles

  • Uses JS variables to pass styles to child elements
var List = React.createClass({
  propTypes: {
    style: View.propTypes.style,
    elementStyle: View.propTypes.style,
  },
  render: function() {
    return (
      <View style={this.props.style}>
        {elements.map((element) =>
          <View style={[styles.element, this.props.elementStyle]} />
        )}
      </View>
    );
  }
});

// ... Render ...
<List style={styles.list} elementStyle={styles.listElement} />

Flexbox

Data Binding

  • Two-way data binding is available in React (ReactLink), but discouraged
  • Adding listeners and REACTing to the changed state are the preferred methods to dealing with REACTive data (jQuery style)

ReactLink (2-way Binding)

var WithLink = React.createClass({
  mixins: [React.addons.LinkedStateMixin],
  getInitialState: function() {
    return {message: 'Hello!'};
  },
  render: function() {
    return <input type="text" valueLink={this.linkState('message')} />;
  }
});

LinkedStateMixin adds a method to your React component called linkState(), that in turn returns a ReactLink object which contains the current value of the React state and a callback to change it.

Non-Data Binding Method

var NoLink = React.createClass({
  getInitialState: function() {
    return {message: 'Hello!'};
  },
  handleChange: function(event) {
    this.setState({message: event.target.value});
  },
  render: function() {
    var message = this.state.message;
    return <input type="text" value={message} onChange={this.handleChange} />;
  }
});

React Native

Developing for iOS

  • Allows you to develop apps as if they were for the web
  • When making changes to the view, you can simply refresh the UI, doesn't require re-compiling
  • You can debug in Chrome

Gesture Handling

  • TouchableHighlight
  • Touchable

Testing

  • "We don't have great test coverage yet, however, so most changes will still require significant manual verification..."  - Official React Docs

Tests

  • Jest tests, run through Node (Unit Tests)
  • Integration tests are run through XCode 
  • Snapshot Testing- Tests that render the tested page and compare them to pre-rendered snapshots of how it should look.

Cons

  • Testing framework not fully featured
  • Re-write our entire front-end
  • Not a framework- therefore requires Backbone or Flux for production
  • If you want a custom Native UI element (directive), you have to write it in Object C
  • React is not yet ready for Android (FB is hoping to release by EOY)
  • Web/Native Hybrid

Pros

  • Fast (Virtual DOM)
  • ES 6
  • Doesn't require learning Objective C or Swift
  • (Relatively) future proof with FB backing
  • Moving away from the DOM (like everyone else)
  • Web/Native Hybrid

Unanswered Questions

  • Load order of JS files
  • Future android/iOS interoperability
  • Future android/iOS syntax

My Opinion of React Native + RealScout

  • If a team is available to work on it, YES ASAP
  • If React might make its way to our web app, YES 
  • If we want to ship a new app ASAP, NO
  • If we are looking for simple, cross native compatibility, NO

React Native

By Davide Curletti