React Native
Cem Turan
Writing native Mobile Apps in Javascript
How to enable a web like workflow on native without sacrificing performance and feel.
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
- iOS and Android are much harder to learn than web
- they need to staff more than 3x the number of engineers + all the overhead
- 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]
loggedInTv = (TextView) findViewById(R.id.login_tv);
loggedInTv.setText( isLoggedIn
? "Logged in as: " + model.name
: "Please log in"
);
loginBtn = (Button) findViewById(R.id.login_btn);
loginBtn.setVisibility( isLoggedIn
? View.GONE
: View.VISIBLE
);
//View construction / XML 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:
- React builds a virtual representation of the UI in memory, i.e. VDOM.
- Diffs it with the old one.
- Calculates the smallest set of changes to make to go from the current UI to the next one.
- 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
- 2,037