Supporting slides of my introductory workshop about React Native in React Alicante 2017.
Source code & Exercises: https://github.com/Limenius/workshop-react-native
Nacho Martin
I write code at Limenius.
We build tailor-made projects,
and provide consultancy
and formation.
We are very happy with React and React Native.
Roadmap:
What is React Native
Starting a project
Working with Styles
Layout
Lists
Navigation
Networking
Touching the native side
Fundamental premise of React
Give me a state and a render() method
that depends on it and forget about
how and when to render.*
Fundamental premise of React
Give me a state and a render() method
that depends on it and forget about
how and when to render.*
* Unless you want more control.
How Native is React Native?
JS Thread
Business logic &
Description of what
components to render
How Native is React Native?
JS Thread Main Thread
UI manipulation
with native
components
Business logic &
Description of what
components to render
How Native is React Native?
JS Thread Main Thread
UI manipulation
with native
components
Business logic &
Description of what
components to render
Bridge
How much code can we reuse?
Tip: if you develop in one platform,
try it in the other from time to time
70%? 80%? 90%?
Option 1: create-react-native-app
Only JS, no iOS or Android code
(outside node_modules)
If you want to modify native code, $ npm run eject
Uses the Expo app to test in real device
Meant to have a quick way of trying
react-native
Option 2: react-native init
Complete project with native code
More control
Needed to use things like CodePush
Doesn’t need external tools to publish to
the store
Play around
Open app/App.js with an editor
<Text style={styles.welcome}>Hi there!</Text>Change the text in
Try nesting
<Text>
<Text style={styles.welcome}>Hi there!</Text>
Amigo
</Text>
Try changing some styles
welcome: {
fontSize: 100,
textAlign: 'center',
margin: 10,
},
Try placing a console.log(‘hi’) before return(… and see it in
Chrome dev tools
Familiarize with errors
What happens if we…
remove a closing tag (</View>)
<View style={styles.container}>
Hi there!
</View>
put text not wrapped in <Text/>
try to comment a JSX line with //
return (
<View style={styles.container}>
<Text style={styles.welcome}>Hi there!</Text>
</View>
<View/>
)
have two root elements
use wrong properties for styles ( rename flex -> flexo )
remove the words export default
Exercise: Build new components
Can you build a new component combining others?
Ideas: Image with footer (<Text/>), two buttons that display different alerts
Can you pass props to that component?
Ideas: Pass the text of the footer with props, pass also the image, pass the titles of the buttons
Can your build a component with local state?
Ideas: Modify the counter to have a “minus 1” button
No CSS. Everything is JS
<View style={{
borderLeftColor: Colors.accent,
borderLeftWidth: 9,
backgroundColor: Colors.backgroundSection,
padding: 18,
paddingVertical: 9,
}}>
No class
No dimensions in pixels
No things like padding: 19 9 3 1
camelCased
Use constants
Exercise 2
FontSizes.gigantic
Colors.background
Container has: a background with color: Colors.highlight
components/MainHeader.js
Image is 40x90
FontSizes.subhead
With weight ‘200’
Colors.background
Pro exercise:Think how would you add support for themes
Dimensions
import {
Dimensions,
} from 'react-native'
const windowSize = Dimensions.get('window')
mainImage: {
height: windowSize.height /3,
width: undefined
},
Our image height depends on the
Height of the window
Use sparingly
components/MovieHeader.js
Dimensions
import {
Dimensions,
} from 'react-native'
const windowSize = Dimensions.get('window')
mainImage: {
height: windowSize.height /3,
width: undefined
},
Our image height depends on the
Height of the window
Use sparingly
Exercise: Can you make another style dependant of
Dimensions?
What will happen if the device is rotated?
Can you find anything in the documentation to fix it?
components/MovieHeader.js
This is flexbox realm
flexDirection
justifyContent
alignItems
alignSelf
flex
alignContent
flexBasis
flexGrow
flexShrink
flexWrap
This is flexbox realm
flexDirection
justifyContent
alignItems
alignSelf
flex
alignContent
flexBasis
flexGrow
flexShrink
flexWrap
flexDirection: ‘column' flexDirection: ‘row’
(Default)
This is flexbox realm
flexDirection
justifyContent
alignItems
alignSelf
flex
alignContent
flexBasis
flexGrow
flexShrink
flexWrap
flexDirection: ‘column' flexDirection: ‘row’
(Default)
main direction
crossdirection
This is flexbox realm
flexDirection
justifyContent
alignItems
alignSelf
flex
alignContent
flexBasis
flexGrow
flexShrink
flexWrap
flexDirection: ‘column' flexDirection: ‘row’
(Default)
main direction
crossdirection
cross direction
maindirection
Exercise 2
Hint: create subviews if you need them
Optional: can you come up with a different layout for any of our three components?
app/components/MainHeader.js
Naive lists, as in the web
export default class Movie extends Component {
constructor(props) {
super(props)
this.state = {
movie: movies.find((movie) => movie.name === 'Pulp Fiction')
}
}
render() {
return (
<View>
<MovieHeader movie={this.state.movie}/>
{ this.state.movie.actors.map(actor => (
<ListItem key={actor} name={actor} image={actors[actor].image}/>
))}
</View>
)
}
}
app/components/Movie.js
Naive lists, as in the web
export default class Movie extends Component {
constructor(props) {
super(props)
this.state = {
movie: movies.find((movie) => movie.name === 'Pulp Fiction')
}
}
render() {
return (
<View>
<MovieHeader movie={this.state.movie}/>
{ this.state.movie.actors.map(actor => (
<ListItem key={actor} name={actor} image={actors[actor].image}/>
))}
</View>
)
}
}
Important to help the reconciler do its work
app/components/Movie.js
Exercise
git checkout lists
Can you build a list of movies in
app/components/MovieList.js ?
(To discard your changes)
git reset HEAD --hard
FlatList
Highly optimized List component
Features:
• Scroll loading (onEndReached).
• Pull to refresh (onRefresh / refreshing).
• Configurable viewability (VPV) callbacks (onViewableItemsChanged / viewabilityConfig).
• Horizontal mode (horizontal).
• Intelligent item and section separators.
• Multi-column support (numColumns)
• scrollToEnd, scrollToIndex, and scrollToItem
• Better Flow typing.
Exercise
Can you use FlatList in
app/components/MovieList.js ?
git checkout flatLists
item => item
reminder
In this case works as
function(item) {
return item
}
git reset HEAD —hard
(To discard your changes)
Exercise
Can you make a navigation transition from Movie to
app/components/Actor ?
Steps:
- Declare the screen in app/App.js
- Use a TouchableHighlight to capture onPress in the actors
list of <Movie/>
- Provide an appropriate title in <Actor/>
- Make the actor displayed based on
props.navigation.state.params.name
Optional: have a look at
https://reactnavigation.org/docs/navigators/stack#StackNavigatorConfig
And tweak the navigation (Ideas: mode modal, add something to headerRight)
Let’s do it
"rnpm": {
"assets": ["./assets/fonts/"]
}
package.json
git checkout mod-native
(To discard your changes)
git reset HEAD --hard
Let’s do it
"rnpm": {
"assets": ["./assets/fonts/"]
}
package.json
react-native link
git checkout mod-native
(To discard your changes)
git reset HEAD --hard
Assets linked
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: android/app/src/main/assets/fonts/OleoScript-Bold.ttf
new file: android/app/src/main/assets/fonts/OleoScript-Regular.ttf
modified: ios/travolta.xcodeproj/project.pbxproj
modified: ios/travolta/Info.plist
modified: package.json
Summary:
What is React Native
Starting a project
Working with Styles
Layout
Lists
Navigation
Networking
Touching the native side