The Gist of React Native

Preview:

Citation preview

THE GIST OF REACT-NATIVEWhat it is,

Why you’d use it

August 11, 2016

Darren Cruse darren.cruse@gmail.com

This Talk is in Beta

Expect Bugs and

Possible Crashes

send feedback to: darren.cruse@gmail.com

(my journey thru UI development developments)

About your speaker…

• 51 years old (old old old so very old grim

reaper get away from me!)

• used various languages:

asm, C, C++, Perl, Java, Groovy, Javascript

• did desktop GUI programming before the

web (Mac, Unix X Windows, Java Swing)

• spent the last 13 years doing web

applications

• haven’t done any mobile apps in the app

stores

• I’m still learning react-native  

My last 13 years doing web applications

(too much code, esp. for so-so user experiences)

And then this guy famously said about html5…

This seemed part of a “meme”…

The prevalent (though not universal) idea that:

“To provide the best user experience you have to use native platform SDKs and languages, not cross platform tools and e.g. not the hybrid phonegap/cordova approach”

*Apple’s early fights against flash on iOS, the restrictions against interpreted code, etc. seemed part of this “meme” as well.

Was the Mobile Train Passing Me By?

So I bought all the toys

And started doing my homework…

BUT OMG…

Web apps during the day, and all this too?

So I started a personal quest evaluating cross platform mobile tools on my weekends…

Titanium

RunRev LiveCode

NativeScriptTabris.js

JavaFX

Adobe Flex

Xamarin

Lambda Native

Qt Quick QML

Famo.usjQuery Mobile

Sencha

But Mobile remained a side interest…

(Nylas email client written in html/css with Electron)

Then recently came some great html UIs

(Atom editor written in html/css with Electron)

Then recently came some great html UIs

(Deco react-native IDE written in html/css with Electron - irony?)

Then recently came some great html UIs

So maybe html5 was underestimated?

*Though I notice many of these great hybrid html based apps have an emphasis on *text* - maybe not a coincidence?

And then I see stuff like this…

https://yahoodevelopers.tumblr.com/post/127636051988/seven-years-into-the-mobile-revolution-content-is

I’M SO CONFUSED!!

(do I want to focus on web apps or on native apps?!)

BUT THEN CAME:

REACT AND

REACT-NATIVE

AND IT’S NO LONGER

“WEB APPSOR

NATIVE APPS”

IT’S

“WEB APPSAND

NATIVE APPS!!”

SO…

REACT

=USE YOUR

WEB DEVELOPER SKILLSFOR WEB APPS

(AS YOU’D EXPECT)

AND:

REACT-NATIVE

=USE YOUR WEB DEVELOPER SKILLS

FORMOBILE APPS

(BUT MINUS THE HTML)

END OF STORY.MY QUEST HAS ENDED!

(MAYBE?)

BUT WAIT YOU SAY?

DIDN’T YOU ALSO JUST MAKE A PITCH FOR:

PHONEGAP/CORDOVA,IONIC,

ELECTRON,ETC?

SINCE THEY TOO LET YOU DEVELOP MOBILE APPS

USING YOUR “WEB DEVELOPER SKILLS”?

MY DEFINITIVE ANSWER:

MY DEFINITIVE ANSWER:

YES AND NO

MY DEFINITIVE ANSWER:

YES AND NO

END OF STORY.

MY DEFINITIVE ANSWER:

YES AND NO

END OF STORY.

(KIDDING)

The React-Native Folks would say this:

Those other tools are fighting that “meme”.

The meme that you *must* write mobile apps using native SDKs for the best possible user experience.

We (the folks behind react-native) are not.

*We* are truly native mobile apps without compromise!!

More details:

• React-native is truly claiming they are super close to the goal that you can write cross-platform apps that are indistinguishable to the user from those you wrote directly using the native sdks.

• They say they rejected the idea (like from java) of “write once run anywhere” knowing that would lead to compromises for the user experience because the browser, iOS, and Android *are different*. They *do* have different “look and feels”, “style guides”, etc.

• Their motto is “learn once write anywhere” meaning you learn the react programming model and apply that uniquely on each platform.

• In practice this means having a lot of shared javascript code between your browser (react), iOS and Android (react-native) applications, but with a (hopefully) small amount of code (and UI markup) using the unique platform SDKs if and when needed.

So what is this “React Programming Model”? (note: react as opposed to react-native)

• HTML *in* your javascript Code (not a separate template)

• React Components (i.e. “Custom Tags”)

• Explicit definition and handling of “program state”

• UI as a *function* of that state

• No direct manipulation of the DOM

• Because the framework *automatically* updates the UI for you

HTML *in* your javascript Code = JSX (not a separate template)

TodoApp.js

/** @jsx React.DOM */var React = require('react');var TodoList = require('./TodoList');

class TodoApp {

getInitialState () {return {

allTodos: TodoStore.getAll() };

}

render () {return (

<div><Header /><TodoList todos={this.state.allTodos} /><Footer todos={this.state.allTodos} />

</div>)

}}

module.exports = React.createClass(TodoApp.prototype);

example code from: https://github.com/edvinerikson/ES6-TodoMVC-React

curly braces escape out to javascript when inside JSX

tags.

React Components• i.e. “Custom Tags”. don’t just use html - invent your own tags! Similar

(but incompatible) to Angular “Directives” and W3C Web Components https://facebook.github.io/react/docs/webcomponents.html

TodoItem.js/** @jsx React.DOM */var React = require('react');

var TodoItem = require('./TodoItem');

class TodoList {

render () {

return (<section id="main">

<input id="toggle-all" type="checkbox" /> <label htmlFor="toggle-all">Mark all as completed</label>

<ul id="todo-list">{this.props.todos.toJSON().map((todo) => {

return <TodoItem key={todo.id} todo={todo} />})}

</ul></section>

)}

}

module.exports = React.createClass(TodoList.prototype);

TodoList.js

/** @jsx React.DOM */var React = require('react');

class TodoItem { // stuff (omitted for brevity)}

module.exports = React.createClass(TodoItem.prototype);

note the components are just CommonJS

modules

Explicit definition and handling of “program state”

/** @jsx React.DOM */var React = require('react');var TodoTextInput = require('./TodoTextInput');

class TodoItem {

getInitialState () { return {isEditing: false} }

render () {let todo = this.props.todo;let input;if(this.state.isEditing) {

input = <TodoTextInput className="edit" onSave={this.setState({isEditing: false})} value={todo.title} />

}return ( <li className={cx({'completed': todo.completed,'editing': this.state.isEditing})} key={todo.id}> <div className="view"> <input className="toggle" type="checkbox" checked={todo.completed}

onChange={this._onToggleComplete} /> <label onDoubleClick={this._onDoubleClick}> {todo.title} </label> <button className="destroy" onClick={this._onDestroyClick} /> </div> {input} </li>)

}}

UI as a function of that state UI = f(state)

/** @jsx React.DOM */var React = require('react');var TodoTextInput = require('./TodoTextInput');

class TodoItem {

getInitialState () { return {isEditing: false} }

render () {let todo = this.props.todo;let input;if(this.state.isEditing) {

input = <TodoTextInput className="edit" onSave={this.setState({isEditing: false})} value={todo.title} />

}return ( <li className={cx({'completed': todo.completed,'editing': this.state.isEditing})} key={todo.id}> <div className="view"> <input className="toggle" type="checkbox" checked={todo.completed}

onChange={this._onToggleComplete} /> <label onDoubleClick={this._onDoubleClick}> {todo.title} </label> <button className="destroy" onClick={this._onDestroyClick} /> </div> {input} </li>)

}}

"No direct manipulation of the DOM” and "the framework automagically updates the UI for you"

• You’re using the react “Virtual DOM” (what JSX is transpiled into). Note this can run under node just fine (e.g. for server side rendering).

• React internally uses “DOM Diffing” to identify and update only the parts of the DOM that really need to change.

diagram from: https://www.infoq.com/articles/react-native-introduction

HOW’S THIS DIFFERENTIN REACT-NATIVE?

THE KEY DIFFERENCE:

THERE IS NO BROWSER

AND SO THERE IS NO BROWSER DOM

For the programmer: it’s almost the same

• It’s just that instead of html tags we now have tags corresponding to native widgets

• So in react-native the “DOM Diffing” plumbing is replaced with code that renders UI using native widget SDKs.

diagram from: https://www.infoq.com/articles/react-native-introduction

The “Bridge”• The Bridge allows asynchronous calling from JS to Native and from Native to

JS. Likewise native events are sent to the JS event handlers.

• JSON messages are passed

• These run in different threads - usually on the one mobile device

• But you can also run the JS in chrome over a websocket in order to live edit and even use the chrome debugger against your running mobile app - this is a great developer experience(!!)

diagram from: https://www.infoq.com/articles/react-native-introduction

Javascript VM

Native Code

Regarding The “Developer Experience”: Here’s the Developer Menu

(this appears when you

“shake gesture” your app)

An example of Debugging JS in Chrome

You can use “.ios.js” and “.android.js” extensions (though you don’t often need to)

example code from: https://github.com/thebakeryio/todomvc-react-native

render() { return ( <View style={ styles.container }> { Platform.OS === 'ios' ? <AddTodoItem /> : null } <MainNavigation /> </View> ); }

Or you can also look at “Platform.OS” within your “generic” code files:

Some example code (part of the ios file from the previous slide)

index.ios.jsclass MainNavigation extends Component {

render() { const children = mainNavigation.routes.map( (tab, i) => {

return ( <TabBarIOS.Item key={tab.key} icon={tab.icon} selectedIcon={tab.selectedIcon} title={tab.title} onPress={ () => dispatch(jumpTo(i, mainNavigation.key)) }

selected={this.props.mainNavigation.index === i}> { this._renderTabContent(tab) } </TabBarIOS.Item> );

});

return ( <TabBarIOS> {children} </TabBarIOS> ); }

_renderTabContent(tab) { return ( <View style={ styles.container }> <TodoList filter={tab.key} /> </View> ); } }

Some example code (part of the android file from the previous slide)

index.android.jsclass MainNavigation extends Component { render() { return ( <DrawerLayoutAndroid ref={(drawer) => { this.drawer = drawer; }} drawerWidth={300} drawerPosition={DrawerLayoutAndroid.positions.Left} renderNavigationView={this._renderNavigation.bind(this)}> {this._renderContent()} </DrawerLayoutAndroid> ); }

_renderTabContent(tab) { return ( <View style={ styles.container }> <TodoList filter={tab.key} /> </View> ); }

_renderContent() { return ( <View style={ styles.container }> <ToolbarAndroid style={androidToolbarStyle} navIcon={navigationIcon} onIconClicked={() => this.drawer.openDrawer()} title={selectedTab.title} /> <AddTodoItem /> {this._renderTabContent(selectedTab)} </View> ); }}

note some of the top level nav components

differ between iOS and android but our “TodoList”

component does not.

CSS is supported, with Flexbox for layout (but the CSS is done in javascript)

index.ios.js

import { StyleSheet } from 'react-native';

export default StyleSheet.create({ container: { flex: 1 }, header: { fontSize: 50, textAlign: 'center', color: 'rgba(175, 47, 47, 0.15)', marginTop: 50, marginBottom: 100 }, navigationMenuItem: { borderBottomWidth: StyleSheet.hairlineWidth, borderBottomColor: '#ededed', flexDirection: 'row', paddingTop: 15, paddingBottom: 15, paddingLeft: 15 }, label: { fontSize: 24, marginLeft: 10 }});

in this case the styles have been put in their own module so both the iOS and Android versions could use them. Since it’s just javascript sometimes it’s just in the component’s module file with the rest.

import styles from ‘./styles';

(other stuff then…)

_renderTabContent(tab) { return ( <View style={ styles.container }> <TodoList filter={tab.key} /> </View> ); }

styles.js

STATE OF REACT-NATIVE

(AS OF AUG 2016)

React-Native is still young (yet it’s being used anyway)

• Current (as of August 2016) version is 0.32

• Only iOS and Android are officially supported by Facebook

• Outside projects are in development for using React-Native to build:

•Windows “Universal Apps”

•Mac OS X desktop apps

•Ubuntu Desktop Apps

•AppleTV Apps

•Samsung Tizen SmartTV/SmartWatch Apps

And for some of you…

A React Native renderer for Angular 2

http://angularjs.blogspot.com/2016/04/angular-2-react-native.html

List of production apps:

https://facebook.github.io/react-native/showcase.html

React Native Job Market (Aug 2016) # of jobs searching indeed.com for “react native”

California: 78

New York: 26

Pennsylvania 23

Texas: 22

Washington State: 14

Illinois: 11

Missouri: 1note: many of the above are not *directly* react-native projects, but show because they list it as a “nice to have”.

GETTING STARTED

Some Tips

• instructions at:

https://facebook.github.io/react-native/docs/getting-started.html

• for developing for android:

you can use windows, linux, or Mac as your development machine

• for developing for iOS:

you have to have a Mac for your development machine.

in fact I had trouble with react-native on an older Mac running Mavericks - I actually upgraded to El Capitan just for react-native.

(I don’t now if this has been reported by others but just a warning FYI)

RESOURCES

official main site: https://facebook.github.io/react-native/

easier to remember: http://www.reactnative.com

docs link on the left goes to

facebook site

Books

React-Native Themes and Starter Kits…

https://strapmobile.com

googling shows up quite a few both free and commercial…

The one to the right is called “Native Starter Kit”

(click image for animation)

“Native Starter Kit Flat Theme”

https://strapmobile.com

just another example…

(click image for animation)

Theme Example: Material Design

https://github.com/binggg/MaterialReactNative

again - just an example (there’s even multiple Material Design projects)

Caveats (It’s not all wine and roses!)

Note react-native is building and deploying full android and iOS apps using all the same build and deployment tools that a natively written app would use.

As I put slides away and went back to trying some code examples, I was hitting some errors running various examples written for older and/or newer versions of react-native than the one I have installed on my machine.

Maybe I need to learn how to properly upgrade react-native and/or projects to work with newer versions of react-native, or maybe this is an area for improvement in react-native as it matures.

Debugging the errors (e.g. java compilation errors) benefitted from having a little java/android or iOS development experience.

It makes me think at a serious company targeting browser, android, and iOS they will benefit greatly from an android developer and an iOS developer. Even if the rest of the team are javascript developers.

It could still be *one team* so it’s much better than the alternative of having *three* teams. But it’s not all wine and roses (this is different than typical browser development!).

RESOURCESMost but not all repeated from the previous slides but:

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

http://www.reactnative.com

https://facebook.github.io/react-native/showcase.html

https://react.parts/native

https://strapmobile.com

https://github.com/binggg/MaterialReactNative

http://shop.oreilly.com/product/0636920041511.do

https://www.packtpub.com/application-development/getting-started-react-native

THANKS

(AND AS BRENDON EICH SAYS…)

http://brendaneich.github.io/ModernWeb.tw-2015/#74