Expo is a set of tools built around React Native
Expo also has docs you can reference if you have questions specific to the tool.
You can also ask for help at Expo forums .
npm install -g expo-cli
expo init AwesomeProject
cd AwesomeProject
npm start
npm run android
npm run ios # macOS only
It requires Xcode or Android Studio to get started
export ANDROID_HOME=$HOME /Android/Sdk
export PATH=$PATH :$ANDROID_HOME /emulator
export PATH=$PATH :$ANDROID_HOME /tools
export PATH=$PATH :$ANDROID_HOME /tools/bin
export PATH=$PATH :$ANDROID_HOME /platform-tools
npx react-native init AwesomeProject
npx react-native init AwesomeTSProject --template react-native-template-typescript
React Native is like React, but it uses native components instead of web components as building blocks.
you need to understand some of the basic React concepts, like JSX , components, state
, and props
import React , { Component } from 'react' ;
import { Text , View } from 'react-native' ;
export default class HelloWorldApp extends Component {
render ( ) {
return (
< View style = { { flex : 1 , justifyContent : "center" , alignItems : "center" } } >
< Text > Hello, world!< / Text >
< / View >
) ;
}
}
1.2.2 What’s going on here?
ES2015 (also known as ES6) is a set of improvements to JavaScript.
but not yet supported by all browsers, so often it isn’t used yet in web development.
import
, from
, class
, and extends
in the example above are all ES2015 features.
Components
So this code is defining HelloWorldApp
, a new Component
.
Most components can be customized when they are created, with different parameters.
These creation parameters are called props
, short for properties.
one basic React Native component is the Image
.
When you create an image, you can use a prop named source to control what image it shows.
import React , { Component } from 'react' ;
import { Image } from 'react-native' ;
export default class Bananas extends Component {
render ( ) {
let pic = {
uri : 'https://upload.wikimedia.org/a.jpg'
} ;
return (
< Image source = { pic } style = { { width : 193 , height : 110 } } / >
) ;
}
}
There are two types of data that control a component: props
and state
.
props
are set by the parent and they are fixed throughout the lifetime of a component.
For data that is going to change, we have to use state
.
You might set state when you have new data from the server.
import React , { Component } from 'react' ;
import { Text , View } from 'react-native' ;
class Blink extends Component {
componentDidMount ( ) {
// Toggle the state every second
setInterval ( ( ) => (
this . setState ( previousState => (
{ isShowingText : ! previousState . isShowingText }
) )
) , 1000 ) ;
}
//state object
state = { isShowingText : true } ;
render ( ) {
if ( ! this . state . isShowingText ) {
return null ;
}
return (
< Text > { this . props . text } < / Text >
) ;
}
}
export default class BlinkApp extends Component {
render ( ) {
return (
< View >
< Blink text = 'I love to blink' / >
< Blink text = 'Yes blinking is so great' / >
< Blink text = 'Why did they ever take this out of HTML' / >
< Blink text = 'Look at me look at me look at me' / >
< / View >
) ;
}
}
All of the core components accept a prop named style
.
The style names and values usually match how CSS works on the web.
names are written using camel casing, e.g. backgroundColor
rather than background-color
.
import React , { Component } from 'react' ;
import { StyleSheet , Text , View } from 'react-native' ;
const styles = StyleSheet . create ( {
bigBlue : {
color : 'blue' ,
fontWeight : 'bold' ,
fontSize : 30 ,
} ,
red : {
color : 'red' ,
} ,
} ) ;
export default class LotsOfStyles extends Component {
render ( ) {
return (
< View >
< Text style = { styles . red } > just red< / Text >
< Text style = { styles . bigBlue } > just bigBlue< / Text >
< Text style = { [ styles . bigBlue , styles . red ] } > bigBlue, then red< / Text >
< Text style = { [ styles . red , styles . bigBlue ] } > red, then bigBlue< / Text >
< / View >
) ;
}
}
import React , { Component } from 'react' ;
import { View } from 'react-native' ;
export default class FixedDimensionsBasics extends Component {
render ( ) {
return (
< View >
< View style = { { width : 50 , height : 50 , backgroundColor : 'powderblue' } } / >
< View style = { { width : 100 , height : 100 , backgroundColor : 'skyblue' } } / >
< View style = { { width : 150 , height : 150 , backgroundColor : 'steelblue' } } / >
< / View >
) ;
}
}
import React , { Component } from 'react' ;
import { View } from 'react-native' ;
export default class FlexDimensionsBasics extends Component {
render ( ) {
return (
// Try removing the `flex: 1` on the parent View.
// The parent will not have dimensions, so the children can't expand.
// What if you add `height: 300` instead of `flex: 1`?
< View style = { { flex : 1 } } >
< View style = { { flex : 1 , backgroundColor : 'powderblue' } } / >
< View style = { { flex : 2 , backgroundColor : 'skyblue' } } / >
< View style = { { flex : 3 , backgroundColor : 'steelblue' } } / >
< / View >
) ;
}
}
flexDirection
controls the direction in which the children of a node are laid out.
row
Align children from left to right.
column
(default value) Align children from top to bottom.
row-reverse
Align children from right to left.
column-reverse
Align children from bottom to top.
3.2.1.1 Flex direction code
import React , { Component } from 'react' ;
import { View } from 'react-native' ;
export default class FlexDirectionBasics extends Component {
render ( ) {
return (
< View style = { { flex : 1 , flexDirection : 'row' } } >
< View style = { { width : 50 , height : 50 , backgroundColor : 'powderblue' } } / >
< View style = { { width : 50 , height : 50 , backgroundColor : 'skyblue' } } / >
< View style = { { width : 50 , height : 50 , backgroundColor : 'steelblue' } } / >
< / View >
) ;
}
} ;
3.2.1.2 Compiled direction
justifyContent
describes how to align children within the main axis of their container.
flex-start(default value)
Align children of a container to the start of the container’s main axis.
flex-end
Align children of a container to the end of the container’s main axis.
center
Align children of a container in the center of the container’s main axis.
space-between
Evenly space of children across the container’s main axis, distributing remaining space between the children.
space-around
Evenly space of children across the container’s main axis, distributing remaining space around the children.
space-evenly
Evenly distributed within the alignment container along the main axis.
3.2.3 Justify Content (cont.)
alignItems
describes how to align children along the cross axis of their container.
alignSelf
has the same options and effect as alignItems but instead of affecting the children within a container.
alignContent
defines the distribution of lines along the cross-axis.
The flexWrap
property is set on containers and controls what happens when children overflow the size of the container along the main axis.
4.1.1 Handling Text Input
TextInput
is a Core Component that allows the user to enter text.
onChangeText
prop is called every time the text changed,
onSubmitEditing
prop is called when the text is submitted.
import React , { Component } from 'react' ;
import { Text , TextInput , View } from 'react-native' ;
export default class PizzaTranslator extends Component {
constructor ( props ) { super ( props ) ; this . state = { text : '' } ; }
render ( ) {
return (
< View style = { { padding : 10 } } >
< TextInput style = { { height : 40 } } placeholder = "Type here to translate!"
onChangeText = { ( text ) => this . setState ( { text} ) } value = { this . state . text } / >
< Text style = { { padding : 10 , fontSize : 42 } } >
{ this . state . text . split ( ' ' ) . map ( ( word ) => word && 'pizza' ) . join ( ' ' ) }
< / Text >
< / View >
) ;
}
}
4.2.1.1 Touch button code
import React , { Component } from 'react' ;
import { Button , StyleSheet , View } from 'react-native' ;
export default class ButtonBasics extends Component {
_onPressButton ( ) { alert ( 'You tapped the button!' ) }
render ( ) {
return (
< View style = { styles . container } >
< Button onPress = { this . _onPressButton } title = "Press Me" / >
< / View >
) ;
}
}
const styles = StyleSheet . create ( {
container : { flex : 1 , justifyContent : 'center' } ,
buttonContainer : { margin : 20 } ,
alternativeLayoutButtonContainer : {
margin : 20 ,
flexDirection : 'row' ,
justifyContent : 'space-between'
}
} ) ;
Kinds of buttons
TouchableHighlight
background will be darkened when the user presses down on the button.
TouchableNativeFeedback
on Android to display ink surface reaction ripples.
TouchableOpacity
provides feedback by reducing the opacity of the button.
TouchableWithoutFeedback
does not provide any feedback.
4.2.2.2 Button’s properties
Button’s properties
onPress
is called by pressing a button.
onLongPress
detect when a user presses and holds a view.
ScrollView
is a generic scrolling container that can contain multiple components and views.
ViewPager
provides swiping horizontally between views.
ScrollView
works best to present a small amount of things of a limited size.
If you have a long list of more items than can fit on the screen, you should use a FlatList
.
import React , { Component } from 'react' ;
import { Button , StyleSheet , View } from 'react-native' ;
export default class ScrollExample extends Component {
render ( ) {
return (
< ScrollView >
< / ScrollView >
) ;
}
}
4.4.1 Using List Views (FlatList)
FlatList
component displays a scrolling list of changing.
FlatList
works well for long lists of data, where the number of items might change over time.
import React , { Component } from 'react' ;
import { FlatList , StyleSheet , Text , View } from 'react-native' ;
export default class FlatListBasics extends Component {
render ( ) {
return (
< View >
< FlatList
data = { [ { key : 'Julie' } ] }
renderItem = { ( { item} ) => < Text > { item . key } < / Text > } / >
< / View >
) ;
}
}
SectionList
displays a set of data broken into logical sections, simmilar to UITableView
on iOS.
import React , { Component } from 'react' ;
import { SectionList , StyleSheet , Text , View } from 'react-native' ;
export default class SectionListBasics extends Component {
render ( ) {
return (
< View style = { styles . container } >
< SectionList
sections = { [
{ title : 'D' , data : [ 'Devin' , 'Dan' , 'Dominic' ] } ,
{ title : 'J' , data : [ 'Jackson' , 'James' , 'Jillian' , 'Jimmy' , 'Joel' , 'John' , 'Julie' ] } ,
] }
renderItem = { ( { item} ) => < Text style = { styles . item } > { item } < / Text > }
renderSectionHeader = { ( { section} ) =>
< Text style = { styles . sectionHeader } > { section . title } < / Text > }
keyExtractor = { ( item , index ) => index }
/ >
< / View >
) ;
}
}
Fetch API
provides an interface for fetching resources (including across the network)
5.1.1.1 Simple fetch example
function getMoviesFromApiAsync ( ) {
return
. then ( ( response ) => response . json ( ) )
. then ( ( responseJson ) => {
return responseJson . movies ;
} )
. catch ( ( error ) => {
console . error ( error ) ;
} ) ;
}
fetch ( 'https://mywebsite.com/endpoint/' , {
method : 'POST' ,
headers : {
Accept : 'application/json' ,
'Content-Type' : 'application/json' ,
} ,
body : JSON . stringify ( {
firstParam : 'yourValue' ,
secondParam : 'yourOtherValue' ,
} ) ,
} )
The WebSocket
object provides the API for creating and managing a WebSocket connection.
sending and receiving data on the connection.
var ws = new WebSocket ( 'ws://host.com/path' ) ;
ws . onopen = ( ) => {
// connection opened
ws . send ( 'something' ) ; // send a message
} ;
ws . onmessage = ( e ) => {
// a message was received
console . log ( e . data ) ;
} ;
ws . onerror = ( e ) => {
// an error occurred
console . log ( e . message ) ;
} ;
ws . onclose = ( e ) => {
// connection closed
console . log ( e . code , e . reason ) ;
} ;