4. 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
5. My last 13 years doing web applications
(too much code, esp. for so-so user experiences)
7. 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.
12. So I started a personal quest evaluating cross
platform mobile tools on my weekends…
Titanium
RunRev
LiveCode
NativeScript
Tabris.js
JavaFX
Adobe Flex
Xamarin
Lambda
Native
Qt Quick QML
Famo.usjQuery Mobile
Sencha
14. (Nylas email client written in html/css with Electron)
Then recently came some great html UIs
15. (Atom editor written in html/css with Electron)
Then recently came some great html UIs
16. (Deco react-native IDE written in html/css with Electron - irony?)
Then recently came some great html UIs
17. 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?
18. And then I see stuff like this…
https://yahoodevelopers.tumblr.com/post/127636051988/seven-years-into-the-mobile-revolution-content-is
33. 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!!
34. 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.
35. 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
36. 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.
37. 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
38. 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>
)
}
}
39. 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>
)
}
}
40. "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
43. 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
44. 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
45. Regarding The “Developer Experience”:
Here’s the Developer Menu
(this appears
when you
“shake gesture”
your app)
47. 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:
49. 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.
50. 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
52. 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
53. And for some of you…
A React Native renderer for Angular 2
http://angularjs.blogspot.com/2016/04/angular-2-react-native.html
54. List of production apps:
https://facebook.github.io/react-native/showcase.html
55. 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: 1
note: many of the above are not *directly* react-native
projects, but show because they list it as a “nice to have”.
57. 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)
62. 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)
63. “Native Starter Kit
Flat Theme”
https://strapmobile.com
just another example…
(click image for animation)
64. Theme Example: Material Design
https://github.com/binggg/MaterialReactNative
again - just an example (there’s even multiple Material Design projects)
65. 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!).
66. RESOURCES
Most 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