React Native Notes For Professionals
React Native Notes For Professionals
React Native Notes For Professionals
Native
80+ pages
of professional hints and
tricks
Please feel free to share this PDF with anyone for free, latest version of this book can be downloaded from:
beautiful people at Stack Overflow. Text content is released under Creative Commons BY-SA, see credits at the end of this book whom contributed t
nal purposes and is not affiliated with official React Native group(s) or company(s) nor Stack Overflow. All trademarks and registered trademarks are
The information presented in this book is not guaranteed to be correct nor accurate, use at your own risk
Please send feedback and corrections to
Professionals 1
Chapter 1: Getting started with React
Native
Section 1.1: Setup for Mac
Installing package manager Homebrew brew
https://developer.apple.com/download/
NOTE: If you have Xcode-beta.app installed along with production version of Xcode.app, make sure you
are using production version of xcodebuild tool. You can set it with:
Git git
*If you have installed XCode, Git is already installed, otherwise run the following
Latest JDK
Android Studio
Ensure the ANDROID_HOME environment variable points to your existing Android SDK. To do that, add this
to your ~/.bashrc, ~/.bash_profile (or whatever your shell uses) and re-open your terminal:
If you installed the SDK without Android Studio, then it may be something like: /usr/local/opt/android-sdk
export ANDROID_HOME=~/Library/Android/sdk
You will need Xcode for iOS and Android Studio for android, node.js, the React Native command line tools, and
Watchman.
Watchman is a tool by Facebook for watching changes in the filesystem. It is highly recommended you
install it for better performance. It is optional.
Node comes with npm, which lets you install the React Native command line interface.
For iOS the easiest way to install Xcode is via the Mac App Store. And for android download and install Android
Studio.
If you plan to make changes in Java code, we recommend Gradle Daemon which speeds up the build.
Use the React Native command line tools to generate a new React Native project called "AwesomeProject", then
run react-native run-ios inside the newly created folder.
You should see your new app running in the iOS Simulator shortly. react-native run-ios is just one way to run your
app - you can also run it directly from within Xcode or Nuclide.
Now that you have successfully run the app, let's modify it.
Open index.ios.js or index.android.js in your text editor of choice and edit some lines.
Hit Command⌘ + R in your iOS Simulator to reload the app and see your change! That's it!
Congratulations! You've successfully run and modified your first React Native app.
Start the terminal and run the following commands to install nodeJS:
curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash -
or
2) Setup Java
4) Setup emulator:
android
Select "SDK Platforms" from within the SDK Manager and you should see a blue checkmark next to "Android 7.0
(Nougat)". In case it is not, click on the checkbox and then "Apply".
5) Start a project
Obs: Always check if the version on android/app/build.gradle is the same as the Build Tools downloaded
on your android SDK
android {
compileSdkVersion XX buildToolsVersion "XX.X.X"
...
Open Android AVD to set up a virtual android. Execute the command line:
android avd
react-native run-android
react-native start
The official setup docs for react-native on windows can be found here. If you need more details there is a granular
guide here.
Tools/Environment
Windows 10
command line tool (eg Powershell or windows command line)
Chocolatey (steps to setup via PowerShell)
The JDK (version 8)
Android Studio
An Intel machine with Virtualization technology enabled for HAXM (optional, only needed if you want to
use an emulator)
After running the last command copy the directory that react-native was installed in. You will need this for Step 4. I
tried this on two computers in one case it was: C:\Program Files (x86)\Nodist\v-x64\6.2.2. In the other it was:
C:\Users\admin\AppData\Roaming\npm
A Step by Step guide with images can be found here for this section.
[Right click] "Start" menu -> System -> Advanced System Settings -> Environment Variables
In the bottom section find the "Path" System Variable and add the location that react-native was installed to in
step 1.
If you haven't added an ANDROID_HOME environment variable you will have to do that here too. While still in
the "Environment Variables" window, add a new System Variable with the name "ANDROID_HOME" and value as
the path to your android sdk.
Then restart the command line as an admin so you can run react-native commands in it.
3) Create your project In command line, navigate to the folder you want to place your project and run
the following command:
cd ProjectName
react-native run-android
You may run into dependency issues. For example, there may be an error that you do not have the correct build
tools version. To fix this you will have to open the sdk manager in Android Studio and download the build tools
from there.
Congrats!
To refresh the ui you can press the r key twice while in the emulator and running the app. To see developer options
you can press ctrl + m.
Chapter 2: Hello World
Section 2.1: Editing index.ios.js or index.android.js
Open index.ios.js or index.android.js and delete everything between the <View> </View>. After that, write and run
<Text> Hello World! </Text> the emulator.
World!
Multiple PropTypes
You can also have multiple propTypes for one props. For example, the name props I'm taking can also be an object,
I can write it as.
static propTypes = {
name: PropTypes.oneOfType([ PropTypes.string, PropTypes.object
])
}
Children Props
There is also a special props called children, which is not passed in like
<Recipe children={something}/>
<Recipe>
<Text>Hello React Native</Text>
</Recipe>
return (
<View style={styles.container}>
{this.props.children}
{this.props.isYummy ? <Text>THIS RECIPE IS YUMMY</Text> : null}
</View>
)
You will have a <Text> component in your Recipe saying Hello React Native, pretty cool hum? And
children: PropTypes.node
render() {
let firstName = 'test'; let lastName = 'name'; return (
<View style={styles.container}>
<Text>{`${firstName} ${lastName}` } </Text>
</View>
);
}
setModalVisibility(visible) {
this.setState({ visibility:
visible,
});
}
render() {
return (
<View style={styles.mainContainer}>
<Modal
animationType={'slide'}
transparent={false}
visible={this.state.visibility}
>
<View style={styles.modalContainer}>
<View>
<Text>I'm a simple Modal</Text>
<Button color="#000"
onPress={() => this.setModalVisibility(!this.state.visibility)} title="Hide Modal"
/>
</View>
</View>
</Modal>
<Button color="#000"
onPress={() => this.setModalVisibility(true)} title="Show Modal"
/>
</View>
);
}
}
_handleButtonPress = () => {
this.setModalVisible(true);
};
render() {
var modalBackgroundStyle = { backgroundColor: 'rgba(0, 0, 0, 0.5)'
};
var innerContainerTransparentStyle = {backgroundColor: '#fff', padding: 20};
return (
<View style={styles.container}>
<Modal
animationType='fade' transparent={true} visible={this.state.modalVisible}
onRequestClose={() => this.setModalVisible(false)}
>
<View style={[styles.container, modalBackgroundStyle]}>
<View style={innerContainerTransparentStyle}>
<Text>This is a modal</Text>
<Button title='close' onPress={this.setModalVisible.bind(this, false)}/>
</View>
</View>
</Modal>
<Button title="Press me"
onPress={this._handleButtonPress}
/>
</View>
);
}
}
setState takes either a key-value object or a function that returns a key-value object
Key-Value Object
this.setState({myKey: 'myValue'});
Function
Using a function is useful for updating a value based off the existing state or props.
You can also pass an optional callback to setState that will be fired when the component has re-rendered with the
new state.
Full Example
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View, TouchableOpacity } from 'react-native';
this.state = { myInteger: 0
}
}
getRandomInteger() {
const randomInt = Math.floor(Math.random()*100);
}
incrementInteger() {
}
render() {
</View>
}
}
}
}
}
}
this.state = { myInteger: 0
}
}
render() {
return(
<View>
<Text>Integer: {this.state.myInteger}</Text>
</View>
)
}
}
Routes to Navigator are provided as objects. You also provide a renderScene function that renders the scene for
each route object. initialRoute is used to specify the first route.
Chapter 8: Styling
Styles are defined within a JSON object with similar styling attribute names like in CSS. Such an object can either be
put inline in the style prop of a component or it can be passed to the function StyleSheet.create(StyleObject) and be
stored in a variable for shorter inline access by using a selector name for it similar to a class in CSS.
If the value of isTrue is true then it will have black background color otherwise white.
This can be inefficient as it has to recreate the object each time the component is rendered. Using a stylesheet is
preferred.
StyleSheet.create() returns an object where the values are numbers. React Native knows to convert these
numeric IDs into the correct style object.
flexDirection
const Direction = (props)=>{
return (
<View style={styles.container}>
<Box/>
<Box/>
<Box/>
<View style={{flexDirection:'row'}}>
<Box/>
<Box/>
<Box/>
</View>
</View>
)
}
Flex size
const FlexSize = (props)=>{
return (
<View style={styles.container}>
<View style={{flex:0.1}}>
<Box style={{flex:0.7}}/>
<Box style={{backgroundColor: 'yellow'}}/>
<Box/>
<Box style={{flex:0.3, backgroundColor: 'yellow'}}/>
</View>
<View style={{flex:0.1}}>
<Box style={{flex:1}}/>
<Box style={{backgroundColor: 'yellow'}}/>
<Box/>
<Box style={{flex:1, backgroundColor: 'yellow'}}/>
</View>
</View>
)
}
Class syntax is not required, you can simply do const name = ({props}) => ( ... ). Generally stateless components are
more concise as a result.
Beneath is an example of two stateless components App and Title, with a demonstration of passing props
between components:
import React from 'react'
import { View, Text, AppRegistry } from 'react-native'
This is the recommended pattern for components, when possible. As in the future optimisations can be made for
these components, reducing memory allocations and unnecessary checks.
Chapter 11: ListView
Section 11.1: Simple Example
ListView - A core component designed for efficient display of vertically scrolling lists of changing data. The minimal
API is to create a ListView.DataSource, populate it with a simple array of data blobs, and instantiate a ListView
component with that data source and a renderRow callback which takes a blob from the data array and returns a
renderable component.
Minimal example:
getInitialState: function() {
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
return {
dataSource: ds.cloneWithRows(['row 1', 'row 2']),
};
},
render: function() {
return (
<ListView dataSource={this.state.dataSource}
renderRow={(rowData) => <Text>{rowData}</Text>}
/>
);
},
ListView also supports more advanced features, including sections with sticky section headers, header and footer
support, callbacks on reaching the end of the available data (onEndReached) and on the set of rows that are visible
in the device viewport change (onChangeVisibleRows), and several performance optimizations.
There are a few performance operations designed to make ListView scroll smoothly while dynamically loading
potentially very large (or conceptually infinite) data sets:
Only re-render changed rows - the rowHasChanged function provided to the data source tells the ListView if
it needs to re-render a row because the source data has changed - see ListViewDataSource for more details.
Rate-limited row rendering - By default, only one row is rendered per event-loop (customizable with the
pageSize prop). This breaks up the work into smaller chunks to reduce the chance of dropping frames while
rendering rows.
Chapter 12: RefreshControl with ListView
Section 12.1: Refresh Control with ListView Full Example
RefreshControl is used inside a ScrollView or ListView to add pull to refresh functionality. at this example we
will use it with ListView
'use strict'
import React, { Component } from 'react';
import { StyleSheet, View, ListView, RefreshControl, Text } from 'react-native'
componentWillMount(){
this.setState({ dataSource:
this.state.dataSource.cloneWithRows(this.state.cars) })
}
render() {
return (
<View style={{flex:1}}>
<ListView refreshControl={this._refreshControl()}
dataSource={this.state.dataSource} renderRow={(car) =>
this._renderListView(car)}>
</ListView>
</View>
)
}
_renderListView(car){
return(
<View style={styles.listView}>
<Text>{car.name}</Text>
<Text>{car.color}</Text>
</View>
)
}
_refreshControl(){
return (
<RefreshControl refreshing={this.state.refreshing}
onRefresh={()=>this._refreshListView()} />
)
}
_refreshListView(){
//Start Rendering Spinner this.setState({refreshing:true}) this.state.cars.push(
{name:'Fusion',color:'Black'},
{name:'Yaris',color:'Blue'}
)
//Updating the dataSource with new data
this.setState({ dataSource:
this.state.dataSource.cloneWithRows(this.state.cars) })
this.setState({refreshing:false}) //Stop Rendering Spinner
}
}
const styles = StyleSheet.create({ listView: {
flex: 1, backgroundColor:'#fff', marginTop:10, marginRight:10, marginLeft:10, padding:10, borderWidth:.5, borderColor:'#dddddd', height:70
}
})
module.exports = RefreshControlExample
here we are updating the array and after that we will update the dataSource. we can use fetch to request
something from server and use async/await.
Chapter 13: WebView
Webview can be used to load external webpages or html content. This component is there by default.
Example Output
react-native-cli: 0.2.0
react-native: n/a - not inside a React Native project directory //Output fromdifferent folder
react-native: react-native: 0.30.0 // Output from the react native project directory
"react-native": "0.32.0"
In terminal:
$ npm install
Followed by
$ react-native upgrade
This will generate android folder and index.android.js inside your app.
$ react-native log-android
iOS
$ react-native log-ios
On latest version of React Native, no need to run the packager. It will run automatically.
By default this starts the server at port 8081. To specify which port the server is on
ws.onopen = () => {
// connection opened
It's easy to configure. For this purpose you can create file axios.js for example:
import * as axios from 'axios';
Requests
To avoid using pattern 'Swiss knife' for every service on your backend you can create separate file with methods for
this within folder for integration functionality:
const UserService = {
getCallToAction() {
return axios.get('api/user/dosomething').then(response => response.data)
.catch(errorHandling);
},
}
export default UserService;
Testing
With this lib you can set to axios any responce you want for testing it. Also you can configure some special errors
for your axois'es methods. You can add it to your axios.js file created in prevous step:
for example.
Redux Store
Sometimes you need to add to headers authorize token, that you probably store in your redux store.
In this case you'll need another file, interceptors.js with this function:
axios.interceptors.request.use(getAuthToken(this.state.store));
and then all your requests will be followed with your authorization token.
As you can see axios is very simple, configurable and useful library for applications based on react-native.
Import module
constructor(props){ super(props);
this.socket = SocketIOClient('http://server:3000');
}
Now in order to use your socket connection properly, you should bind your functions in constructor too. Let's
assume that we have to build a simple application, which will send a ping to a server via socket after every 5
seconds (consider this as ping), and then the application will get a reply from the server. To do so, let's first create
these two functions:
_sendPing(){
//emit a dong message to socket server
socket.emit('ding');
}
_getReply(data){
//get reply from socket server, log it to console
console.log('Reply from server:' + data);
}
constructor(props){ super(props);
this.socket = SocketIOClient('http://server:3000');
After that, we also need to link _getReply function with the socket in order to receive the message from the
socket server. To do this we need to attach our _getReply function with socket object. Add the following line to
our constructor:
this.socket.on('dong', this._getReply);
Now, whenever socket server emits with the 'dong' your application will able to receive it.
Chapter 16: Platform Module
Section 16.1: Find the OS Type/Version
The first step is to import Platform from the 'react-native' package like so:
After you've done that, you can go ahead and access the OS type through Platform.OS allowing you to use it in
conditional statements like
If you want to detect the Android version, you can use Platform.Version like so:
For iOS, Platform.Version is returning a String, for complex condition don't forget to parse it.
If the platform specific logic is complex, one can render two different files based on platform. Ex:
MyTask.android.js
MyTask.ios.js
You can also use a local image with a slightly different syntax but same logic like so:
Note: You should give height, width to the image otherwise it won't show.
If the path is available in imagePath then it will be assigned to source else the default image path will be assigned.
Example: Here we added a folder in root called "mystuff", then "fonts", and inside it we placed
our fonts:
Android
FONT-NAME is the words before the extension in file. Example: Your font's file name is Roboto-Regular.ttf, so you
would set fontFamily: Roboto-Regular.
iOS
FONT-NAME is "Full Name" found after right clicking, on the font file, then clicking on "Get Info". ( Source:
https://stackoverflow.com/a/16788493/2529614 ), in the screenshot below, the file name is MM Proxima Nova
Ultra bold.otf, however "Full Name" is "Proxima Nova Semibold", thus you would set fontFamily: Proxima Nova
Semibold. Screenshot -
Run react-native run-ios or react-native run-android again (this will recompile with the resources)
2. Make sure that they are included in the Target Membership column
Click on the font from the navigator, and check if the font included.
3. Check if the font included as Resource in your bundle
click on your Xcode project file, select "Build Phases, select "Copy Bundle Resources". Check if your font is added.
from the application main folder open Info.plist, click on "Information Property List", and then click the plus sign
(+). from drop down list choose "Fonts provided by application".
expand Fonts Provided by Application and add the Font Name exactly to value column
6. Use it in the Application
Note: this.onMainScreen() and this.goBack() are not built in functions, you also need to implement those.
(https://github.com/immidi/react-native/commit/ed7e0fb31d842c63e8b8dc77ce795fac86e0f712)
componentWillMount registers an event listener to handle the taps on the back button. It checks if there is another
view in the history stack, and if there is one, it goes back -otherwise it keeps the default behaviour.
this.navigator;
}
renderScene(route, navigator) {
this.navigator = navigator;
return (
<SceneContainer title={route.title} route={route} navigator={navigator} onBack={() => {
if (route.index > 0) { navigator.pop();
}
}}
{...this.props} />
);
}
render() {
return (
<Navigator initialRoute={<View />}
renderScene={this.renderScene.bind(this)} navigationBar={
<Navigator.NavigationBar style={{backgroundColor: 'gray'}} routeMapper={RouteMapper} />
} />
);
}
};
1. If there are more than 1 screen on stack, device back button will show previous screen.
2. If there is only 1 screen on stack, device back button will exit app.
constructor(props) { super(props)
this.handleBackButtonClick = this.handleBackButtonClick.bind(this);
}
componentWillMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackButtonClick);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButtonClick);
}
In this case, no need to handle anything on that screen where you want to exit app.
{...}
ComponentWillMount(){ BackHandler.addEventListener('hardwareBackPress',()=>{
if (!this.onMainScreen()) {
this.goBack(); return true;
}
return false;
});
}
Chapter 21: Run an app on device
(Android Version)
Section 21.1: Running an app on Android Device
1. adb devices
Is your phone displaying? If not, enable developer mode on your phone, and connect it by USB.
2. adb reverse tcp:8081 tcp:8081 :
In order to link correctly your phone and that React-Native recognize him during build. (NOTE:Android
Version 5 or above.)
3. react-native run-android :
To run the app on your phone.
4. react-native start :
In order to start a local server for development (mandatory). This server is automatically started if you
use the last version of React-native.
Chapter 22: Native Modules
Section 22.1: Create your Native Module (IOS)
Introduction
from http://facebook.github.io/react-native/docs/native-modules-ios.html
Sometimes an app needs access to platform API, and React Native doesn't have a corresponding module
yet. Maybe you want to reuse some existing Objective-C, Swift or C++ code without having to
reimplement it in JavaScript, or write some high performance, multi-threaded code such as for image
processing, a database, or any number of advanced extensions.
A Native Module is simply an Objective-C Class that implements the RCTBridgeModule protocol.
Example
In your Xcode project create a new file and select Cocoa Touch Class, in the creation wizard choose a name for
your Class (e.g. NativeModule), make it a Subclass of: NSObject and choose Objective-C for the language.
@end
RCT_EXPORT_MODULE() will make your module accessible in JavaScript, you can pass it an optional
argument to specify its name. If no name is provided it will match the Objective-C class name.
RCT_EXPORT_METHOD() will expose your method to JavaScript, only the methods you export using this macro will be
accessible in JavaScript.
Linking.openURL(url)
.catch(err => console.error('An error occurred ', err))
The preferred method is to check if any installed app can handle a given URL beforehand.
Linking.canOpenURL(url)
.then(supported => {
if (!supported) { console.log('Unsupported URL: ' + url)
} else {
return Linking.openURL(url)
}
}).catch(err => console.error('An error occurred ', err))
URI Schemes
Target App Example Reference
Web Browser https://STACKOVERFLOW.COM
Phone tel:1-408-555-5555 Apple
Mail mailto:[email protected] Apple
SMS sms:1-408-555-1212 Apple
Apple Maps http:// MAPS . APPLE . COM /? LL =37.484847,-122.148386
Apple Google Maps geo:37.7749,-122.4194 Google
iTunes See iTunes Link Maker Apple
Facebook fb://profile Stack Overflow
YouTube http://www.youtube.com/v/oHg5SJYRHA0 Apple
Facetime FACETIME://[email protected] Apple
iOS Calendar calshow:514300000 [1] iPhoneDevWiki
[1] Opens the calendar at the stated number of seconds since 1. 1. 2001 (UTC?). For some reason this API is
undocumented by Apple.
componentDidMount() {
const url = Linking.getInitialURL()
.then((url) => {
if (url) {
console.log('Initial url is: ' + url)
}
}).catch(err => console.error('An error occurred ', err))
}
For react-native you can use rulesets for javascript, react and react-native.
Common ESLint rules with motivation and explanations for javascript you can find here:
https://github.com/eslint/eslint/tree/master/docs/rules . You can simply add ready ruleset from ESLint developers by adding
in your .eslintr.json to 'extends' node 'eslint:recommended'. ( "extends": ["eslint:recommended"] ) More about
ESLint configuring you can read here: http://eslint.org/docs/developer-guide/development-environment . It's recommended to
read full doc about this extremely useful tool.
Next, full docs about rules for ES Lint react plugin you can find here:
https://github.com/yannickcr/eslint-plugin-react/tree/master/docs/rules . Important note: not all rules from react
are relative to react-native. For example: react/display-name and react/no-unknown-property for example.
Another rules are 'must have' for every project on react-native, such as react/jsx-no-bind and react/jsx-key.
And finaly, there is a plugin explicidly for react-native: https://github.com/intellicode/eslint-plugin-react-native Note: If you split
your styles in separate file, rule react-native/no-inline-styles will not work.
For correct working of this tool in react-native env you might need to set value or 'env' in your config to this:
.auth().signInWithEmailAndPassword(email, password)
his.onLoginSuccess)
Posts.js
render() {
return <PostsList posts={this.state.posts}/>
}
PostsList.js
componentDidMount() {
this.setState({dataSource: this.getDataSource(this.props.posts)});
}
componentWillReceiveProps(props) {
this.setState({dataSource: this.getDataSource(props.posts)});
}
render() {
return(
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
enableEmptySections={true}
/>
);
}
}
I want to point out that in Posts.js, I'm not importing firebase because you only need to import it once, in the main
component of your project (where you have the navigator) and use it anywhere.
This is the solution someone suggested in a question I asked when I was struggling with ListView. I
thought it would be nice to share it.
Source: [http://stackoverflow.com/questions/38414289/react-native-listview-not-rendering-data-from-firebase][1]
Chapter 26: Navigator Best Practices
Section 26.1: Navigator
Navigator is React Native's default navigator. A Navigator component manages a stack of route objects, and
provides methods for managing that stack.
<Navigator
ref={(navigator) => { this.navigator = navigator }} initialRoute={{ id: 'route1', title: 'Route 1' }} renderScene={this.renderScene.bind(this)}
configureScene={(route) => Navigator.SceneConfigs.FloatFromRight} style={{ flex: 1 }}
navigationBar={
// see "Managing the Navigation Bar" below
<Navigator.NavigationBar routeMapper={this.routeMapper} />
}
/>
First of all, notice the initialRoute prop. A route is simply a javascript object, and can take whatever shape you
want, and have whatever values you want. It's the primary way you'll pass values and methods between
components in your navigation stack.
The Navigator knows what to render based on the value returned from its renderScene prop.
renderScene(route, navigator) {
if (route.id === 'route1') {
return <ExampleScene navigator={navigator} title={route.title} />; // see below
} else if (route.id === 'route2') {
return <ExampleScene navigator={navigator} title={route.title} />; // see below
}
}
function ExampleScene(props) {
function forward() {
// this route object will passed along to our `renderScene` function we defined above.
props.navigator.push({ id: 'route2', title: 'Route 2' });
}
function back() {
// `pop` simply pops one route object off the `Navigator`'s stack
props.navigator.pop();
}
return (
<View>
<Text>{props.title}</Text>
<TouchableOpacity onPress={forward}>
<Text>Go forward!</Text>
</TouchableOpacity>
<TouchableOpacity onPress={back}>
<Text>Go Back!</Text>
</TouchableOpacity>
</View>
);
}
You can configure the Navigator's transitions with the configureScene prop. This is a function that's passed the
route object, and needs to return a configuration object. These are the available configuration objects:
Navigator.SceneConfigs.PushFromRight (default)
Navigator.SceneConfigs.FloatFromRight
Navigator.SceneConfigs.FloatFromLeft
Navigator.SceneConfigs.FloatFromBottom
Navigator.SceneConfigs.FloatFromBottomAndroid
Navigator.SceneConfigs.FadeAndroid
Navigator.SceneConfigs.HorizontalSwipeJump
Navigator.SceneConfigs.HorizontalSwipeJumpFromRight
Navigator.SceneConfigs.VerticalUpSwipeJump
Navigator.SceneConfigs.VerticalDownSwipeJump
You can return one of these objects without modification, or you can modify the configuration object to
customize the navigation transitions. For example, to modify the edge hit width to more closely emulate the iOS
UINavigationController 's interactivePopGestureRecognizer :
configureScene={(route) => {
return {
...Navigator.SceneConfigs.FloatFromRight, gestures: {
pop: {
...Navigator.SceneConfigs.FloatFromRight.gestures.pop, edgeHitWidth: Dimensions.get('window').width / 2,
},
},
};
}}
The Navigator component comes with a navigationBar prop, which can theoretically take any properly configured
React component. But the most common implementation uses the default Navigator.NavigationBar. This takes a
routeMapper prop that you can use to configure the appearance of the navigation bar based on the route.
A routeMapper is a regular javascript object with three functions: Title, RightButton, and LeftButton. For example:
const routeMapper = {
return (
<TouchableOpacity
onPress={() => navigator.pop()} style={styles.navBarLeftButton}
>
<Text>Back</Text>
</TouchableOpacity>
);
},
See more
For more detailed documentation of each prop, see the the official React Native Documentation for Navigator, and the
React Native guide on Using Navigators.
Install react-navigation
Example:
import { Button, View, Text, AppRegistry } from 'react-native'; import { StackNavigator } from 'react-navigation';
return (
<Button
title='Go to Second Page' onPress={() =>
navigate('SecondPage', { name: 'Awesomepankaj' })
}
/>
);
}
}
render() {
const { goBack } = this.props.navigation; return (
<View>
<Text>Welcome to Second Page</Text>
<Button
title="Go back to First Page" onPress={() => goBack()}
/>
</View>
);
}
}
key A unique string that can be used to refer to the particular scene.
Example:
Import this file in the main App.js(index file) and render it. For more information can visit this link.
Chapter 27: Navigator with buttons
injected from pages
Section 27.1: Introduction
Instead of bloating your main js file that contains your navigator with buttons. It's cleaner to just inject buttons on-
demand in any page that you need.
//In the page "Home", I want to have the right nav button to show
//a settings modal that resides in "Home" component.
componentWillMount() {
this.props.route.navbarTitle = "Home";
renderScene(route, navigator) {
switch(route.name) {
case "Home":
//You must pass route as a prop for this trick to work properly
return <Home route={route} navigator={navigator} {...route.passProps}/>
default:
return (
<Text route={route} style={styles.container}>
Your route name is probably incorrect {JSON.stringify(route)}
</Text>
);
}
}
render() {
return (
<Navigator
navigationBar={
<Navigator.NavigationBar style={
styles.navbar }
routeMapper={ NavigationBarRouteMapper } />
}
/>
);
}
}
this.props.route.rightNavButton = { text:
"Button",
onPress: this._doSomething.bind(this)
};
}
render() {
return (
<View style={styles.container}>
<Text>You are home</Text>
</View>
);
}
}
Problem statement: I've built my app, I can run it on my local emulator (and also on my android device by
changing debug server). But, I want to build an apk that I can send to someone without access to development
server and I want them to be able to test application.
./app/build/outputs/apk/app-release.apk
Chapter 29: PushNotification
We can add Push Notification to react native app by using the npm module react-native-push-
notification by zo0r. This enables for a cross platform development.
Installation
react-native link
extends Component {
constructor(props){
super(props);
this.NewNotification = this.NewNotification.bind(this);
}
componentDidMount(){
PushNotification.configure({
/**
* (optional) default: true
* - Specified if PERMISSIONS (IOS) and token (android and IOS) will REQUESTED or not,
* - if not, you MUST call PUSHNOTIFICATIONSHANDLER.REQUESTPERMISSIONS() later
*/
requestPermissions: true,
});
NewNotification(){
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}> Push
Notification
</Text>
<View style={styles.Button} >
<Button onPress={()=>{this.NewNotification()}}
title="Show Notification" style={styles.Button}
color="#841584" accessibilityLabel="Show
Notification"
/>
</View>
</View>
);
}
}
'use strict';
this.handleNotification = this.handleNotification.bind(this);
}
handleNotification(notification)
{
console.log('handleNotification');
var notificationId = ''
//your logic to get relevant information from the notification
//here you navigate to a SCENE in your app BASED on the notification info
this.navigator.push({ id: Constants.ITEM_VIEW_ID, item: item });
}
componentDidMount()
{
var that = this;
PushNotification.configure({
that.handleNotification(notification);
},
// ANDROID ONLY: (optional) GCM Sender ID.
senderID: "Vizido",
/**
* (optional) default: true
* - Specified if PERMISSIONS (IOS) and token (android and IOS) will REQUESTED or not,
* - if not, you MUST call PUSHNOTIFICATIONSHANDLER.REQUESTPERMISSIONS() later
*/
requestPermissions: true,
});
}
render()
{
return (
<Navigator
ref={(nav) => this.navigator = nav }
initialRoute={initialRoute}
renderScene={this.renderScene.bind(this)}
configureScene={(route) =>
{
if (route.sceneConfig)
{
return route.sceneConfig;
}
return Navigator.SceneConfigs.FadeAndroid;
}
}
/>
);
}
renderScene(route, navigator)
{
switch (route.id)
{
// do your routing here
case 'mainview':
return ( <MainView navigator={navigator} /> );
default:
return ( <MainView navigator={navigator} /> );
}
}
}
Chapter 30: Render Best Practises
Topic for important notes about specific Component.render method behavoir.
As explained at https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md :
A bind call or arrow function in a JSX prop will create a brand new function on every single render. This is
bad for performance, as it will result in the garbage collector being invoked way more than is necessary. It
may also cause unnecessary re-renders if a brand new function is passed as a prop to a component that
uses reference equality check on the prop to determine if it should update.
<TextInput
onChangeValue={value => this.handleValueChanging(value) }
/>
or
<TextInput
onChangeValue={this.handleValueChanging }
/>
and
For correct context within handleValueChanging function you can apply it in constructor of component:
constructor(){
this.handleValueChanging = this.handleValueChanging.bind(this)
}
Or you can use solutions like this: https://github.com/andreypopp/autobind-decorator and simply add @autobind decorator
to each methos that you want bind to:
@autobind handleValueChanging(newValue)
{
//processing event
}
Chapter 31: Debugging
Section 31.1: Start Remote JS Debugging in Android
You can start the remote debugging from Developer menu. After selecting the enable remote debugging it will open
Google Chrome, So that you can log the output into your console. You can also write debugger syntax into your js
code.
react-native log-android
react-native log-ios
You will now start to see all the log message in this terminal
Chapter 32: Unit Testing
Unit testing is a low level testing practice where smallest units or components of the code are tested.
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start", "test": "jest"
},
"jest": {
"preset": "react-native"
}
You can run run npm test or jest to test in react native. For code example: Link
Credits
Thank you greatly to all the people from Stack Overflow Documentation who helped provide this content,
more changes can be sent to [email protected] for new content to be published or updated