React Native in Action v7 MEAP
React Native in Action v7 MEAP
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
welcome
Thank you for purchasing React Native in Action! With the growing demand for app
development and the increasing complexity that app development entails, React Native comes
along at a perfect time, making it possible for developers to build performant cross platform
native apps much easier than ever before, all with a single programming language: JavaScript.
This book gives any iOS, Android, or web developer the knowledge and confidence to begin
building high quality iOS and Android apps using the React Native Framework right away.
When React Native was released in February of 2015, it immediately caught my attention,
as well as the attention of the lead engineers at my company. At the time, we were at the
beginning stages of developing a hybrid app using Cordova. After looking at React Native, we
made the switch and bet on React Native as our existing and future app development
framework. We have been very pleased at the ease and quality of development that the
framework has allowed the developers at our company, and I hope that once you are finished
reading this book, you will also have a good understanding of the benefits that React Native
has to offer.
Since I began working with React Native at its release, it’s been a pleasure to work with it
and to be involved with its community. I’ve spent much time researching, debugging,
blogging, reading, building things with, and speaking about React Native. In my book, I boil
down what I have learned into a concise explanation of what React Native is, how it works,
why I think it’s great, and the important concepts needed to build high quality mobile apps in
React Native.
Any developer serious about app development or wanting to stay ahead of the curve
concerning emerging and disruptive technologies should take a serious look at React Native,
as it has the potential to be the holy grail of cross-platform app development that many
developers and companies have been hoping for.
—Nader Dabit
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
brief contents
PART 1: GETTING STARTED WITH REACT NATIVE
1 Getting started with React Native
2 Understanding React
3 Building your first React Native App
PART 2: REACT NATIVE APPLICATION DEVELOPMENT
4 Introduction to styling
5 Styling in depth
6 Cross-platform component
7 Navigation
8 Cross-platform APIs
9 iOS-specific components and APIs
10 Android-specific components and APIs
11 Working with network requests
12 Animations
PART 3: DATA ARCHITECTURES & TESTING
13 Data architectures
14 Testing
APPENDIXES
A Installing and running React Native
B Resources
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
1
1
Getting started with React Native
Native mobile application development can be complex. With the complicated environments,
verbose frameworks, and long compilation times, developing a quality native mobile
application is no easy task. It’s no wonder that the market has seen its share of solutions
come onto the scene that attempt to solve the problems that go along with native mobile
application development, and try to somehow make it easier.
At the core of this complexity is the obstacle of cross platform development. The various
platforms are fundamentally different and do not share much of the same development
environments, APIs, or code. Because of this, you must have separate teams working on each
platform, which is both expensive and inefficient.
This is where React Native stands out. React Native is an extraordinary technology. It will
not only improve the way you work as a mobile developer, it will change the way you build
and reason about mobile application development, and how you organize your engineering
team.
This is a very exciting time in mobile application development. We are witnessing a new
paradigm in the mobile development landscape, and React Native is on the forefront of this
shift in how we build and engineer our mobile applications, as it is now possible to build native
performing cross platform apps as well as web applications with a single language and team.
With the rise of mobile devices and the subsequent increase in demand of talent driving
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
2
developer salaries higher and higher, React Native brings to the table a framework that offers
the possibility of being able to deliver quality applications across all platforms at a fraction of
the time and cost while still delivering a high quality user experience and a delightful
developer experience.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
3
<SomeComponent />
)
}
})
The main difference is that the stateless components do not hook into any lifecycle methods
and therefore hold no state of their own, so any data to be rendered has to be passed down as
props. We will discuss all of this in depth later in this chapter, but for now, we will talk about
creating React Native components using ES6 classes.
To get started and begin understanding the flow of React Native, let’s walk through and go
over what happens when a basic React Native Component class is created and rendered
(figure 1.1, listing 1.4).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
4
Something to keep in mind when we discuss the following methods it the concept of mounting. When a
component is mounted, or created, the react component lifecycle is instantiated, triggering the methods we
used above and will discuss below.
At the top of the file, we require React from 'react', as well as View, Text, and StyleSheet
from 'react-native'. View is the most fundamental build block for building React Native
components and the UI in general, and can be thought of like a div in HTML. Text allows us to
create text elements and is comparable to a span tag in HTML. StyleSheet allows us to create
style objects to use in our application. These two packages (react and react-native) are
available as npm modules.
When the component first loads, we set a state object with the variable name in the
constructor (❶) . For data in a React Native application to be dynamic, it either needs to be
set in the state or passed down as props. Here, we have set the state in the constructor and
can therefore change it if we would like by calling:
this.setState({
name: 'Some Other Name'
})
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
5
which would rerender the component. If we did not set the variable in the state, we would not
be able to update the variable in the component.
The next thing to happen in the lifecycle is componentWillMount is called (❷)
.componentWillMount is called before the rendering of the UI occurs.
render is then called (❸) , which examines props and state and then must return either a
single React Native element, null, or false. This means that if you have multiple child
elements, they must be wrapped in a parent element. Here the components, styles, and data
are combined to create what will be rendered to the UI.
The final method in the lifecycle is componentDidMount (❹) . If you need to do any api
calls or ajax requests to reset the state, this is usually the best place to do so.
Finally, the UI is rendered to the device and we can see our result.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
6
come out of the box with React Native, but also a couple of community projects available
through npm.
After learning navigation, we will then cover both cross platform and platform specific APIs
available in React Native and discuss how they work in depth.
It will then be time for us to start working data using network requests, async storage (a
form of local storage), firebase, and websockets.
After that we will dive into the different data architectures and how each of them works to
handle the state of our application
Finally, we will take a look at testing and a few different ways to do so in React Native.
1.4.2 Threading
All JavaScript operations, when interacting with the native platform, are done on separate a
thread, allowing the user interface as well as any animations to perform smoothly. This thread
is where the React application lives, and all API calls, touch events, and interactions are
processed. When there is a change to a native-backed component, updates are batched and
sent to the native side. This happens at the end of each iteration of the event-loop. For most
React Native applications, the business logic runs on the JavaScript thread.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
7
1.4.3 React
A great feature of React Native is that is uses React. React is an open-source JavaScript
library that is also backed by Facebook. It was originally designed to build applications and
solve problems on the web. This framework has become extremely popular and used since its
release, with companies such as Airbnb, Box.com, CodeAcademy, and Dropbox taking
advantage of its quick rendering, maintainability, and declarative UI among other things.
Traditional DOM manipulation is very slow and expensive in terms of performance, and should
be minimized. React bypasses the traditional DOM with something called the ‘Virtual DOM’.
The Virtual DOM is basically a copy of the actual DOM in memory, and only changes when
comparing new versions of the Virtual Dom to old versions of the Virtual DOM. This allows the
minimum number of DOM operations needed to achieve the new state.
1.4.5 Diffing
React takes this idea of diffing and applies it to native components. It takes your UI and sends
the smallest amount of data to the main thread to render it with native components. Your UI
is declaratively rendered based on the state, and React uses diffing to send the necessary
changes over the bridge.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
8
The first thing to do is to mentally break the UI elements up into what they actually represent.
So, in the above mockup, we have a header bar, and within the header bar we have a title and
a menu button. Below the header we have a tab bar, and within the tab bar we have three
individual tabs. Go through the rest of the mockup and think of what the rest of the items
might be as well. These items that we are identifying will be translated into components. This
is the way you should think about composing your UI. When working with React Native, you
should break down common elements in your UI into reusable components, and define their
interface accordingly. When you need this element any time in the future, it will be available
for you to reuse.
Breaking up your UI elements in to reusable components is not only good for code reuse,
but will also make your code very declarative and understandable. For instance, instead of
twelve lines of code implementing a footer, the element could simply be called footer. When
looking at code that is built in this way, it is much easier to reason about and know exactly
what is going on.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
9
Let’s take a look at how the design in Figure 1.2 could be broken up in the way we just
described:
The names I have used here could be whatever makes sense to you. Look at how these items
are broken up and some of them are grouped together. We have logically separated these
items into individual and grouped conceptual components. Next, let’s see how this would look
using actual React Native code.
First, let’s look at how the main UI elements would on our page:
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
10
<Header />
<TabBar />
<ProjectList />
<Footer />
<TabBarItem />
<TabBarItem />
<TabBarItem />
ProjectList:
// Loop through projects array, for each project return:
<Project />
As you can see, we have used the same names that we declared in figure 1.3, though they
could be whatever makes sense to you.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
11
allowing them to spend all of their time in one state of mind when switching between web and
mobile projects. It is also a win for teams who were traditionally split between Android and
iOS, as they can now work together on a single codebase.
To underscore these points, you can also share your data architecture not only cross
platform, but also on the web, if you are using something like Redux, which we will look at in a
later chapter.
1.5.3 Performance
If you follow other cross platform solutions, you are probably aware of solutions such as
PhoneGap, Cordova and Ionic. While these are also viable solutions, the overall consensus is
that the performance has not yet caught up to the experience a native app delivers. This is
where React Native also really shines, as the performance is usually unnoticeable from that of
a native mobile app built using Objective-C or Java.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
12
1.5.6 Transpilation
Transpilation is typically when something known as a transpiler takes source code written in
one programming language and produces the equivalent code in another language. With the
rise of new EcmaScript features and standards, transpilation has spilled over to also include
taking newer versions and yet to be implemented features of certain languages, in our case
JavaScript, and producing compiled standard JavaScript, making the code usable by platforms
that can only process older versions of the language.
React Native uses Babel to do this transpilation step, and it is built in by default. Babel is
an open source tool that transpiles the most bleeding edge JavaScript language features in to
code that can be used today. This means that we do not have to wait for the bureaucratic
process of language features being proposed, approved, and then implemented before we can
use them. We can start using it as soon as the feature makes it into Babel, which is usually
very quickly. JavaScript classes, arrow functions and object destructuring are all examples of
powerful ES2015 features that have not made it into all browsers and runtimes yet, but with
Babel and React Native, you can use them all today with no worries about whether or not they
will work. If you like this, it is also available on the web.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
13
valuable and in demand. Once React Native, or something like it if it comes along, makes
developing desktop and web as well as mobile applications using a single framework
mainstream, there will be a restrucuring and rethinking of how engineering teams are
organized. Instead of a developer being specialized in a certain platform, such as iOS or web,
they will be in charge of features across platforms. In this new era of cross platform and cross
stack engineering teams, developers delivering native mobile, web, and desktop applications
will be more productive and efficient and will therefore be able to demand a higher wage than
a traditional web developer only able to deliver web applications.
Companies that are hiring developers for mobile development stand to benefit the most
out of using React Native. Having everything written in once language makes hiring a lot
easier and less expensive. Productivity also soars when your team is all on the same page,
working within a single technology, which makes collaboration and knowledge sharing easier.
1.5.8 Community
The React community, and by extension the React Native community, is one of the most open
and helpful groups I have ever interacted with. When running into issues that I have not been
able to resolve on my own, by searching online or Stack Overflow, I have reached out directly
to either a team member or someone in the community and have had nothing but positive
feedback and help.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
14
1.5.11 Drawbacks
Now that we’ve gone over all of the benefits of using React Native, let’s take a look at a few
reasons and circumstances where you may not want to choose the framework.
First, React Native is still immature when compared with other platforms such as native
iOS and Android, as well as Cordova. The feature parity is not there yet with either native or
Cordova. While most functionality is now built in, there may be times where you need some
functionality that is not yet available, and this means you will either have to dig into the native
code to build it yourself, hire someone to do it, or not implement the feature at all.
Another thing to think about is the fact that you and or your team will have to learn a
completely new technology if you are not already familiar with React. While most people seem
to agree that React is easy to pick up, if you are already proficient with Angular and Ionic, for
example, and you have an application deadline coming up, it may be wise to go with what you
already know instead of spending the time it takes to learn and train your team on a new tech.
In addition to learning React and React Native, you must also become familiar with Xcode
and the android development environments, which can take some getting used to as well.
Finally, React Native is just a complex abstraction built on top of existing platform APIs.
This means that when newer version of iOS, Android, or other future platforms are released,
there may be a time when React Native will be behind on the new features released with the
newer version of the other platforms, forcing you to have to either build custom
implementations to interact with these new APIs or wait until React Native regains feature
parity with the new release.
1.5.12 Conclusion
React Native has come a long way at a fast pace. Considering all of the knowledgeable people
both in the community and at Facebook working together to improve React Native, I do not
see any serious roadblocks stopping the team and the community from handling most issues
that have not yet been addressed, or that may have yetcome up. Many companies are betting
big on this framework, yet many have chosen to stay native or hybrid at the moment. It would
be a good idea to look at your individual situation and see what type of mobile implementation
works best for you, your company, or your team.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
15
1.6.1 Components
At the core of React Native is the concept of components. React Native has built in
components that you will see me describe as Native components, and you will also build
components using the framework. Components are a collection of data and UI elements that
make up your views and ultimately your application. We will go in depth on how to build,
create and use components in this book.
As we mentioned earlier, React Native components are built using JSX. Let’s run through a
couple of basic examples of what JSX in React Native looks like vs HTML:
1. Text Component
2.View Component
<div> <View>
<span>Hello World 2</span> <Text>Hello World 2</Text>
</div> </View>
3. Touchable Highlight
<button> <TouchableHighlight>
<span>Hello World 2</span> <Text>Hello World 2</Text>
</button> </TouchableHighlight>
As you can see in table 1.1, JSX looks very similar to HTML or XML.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
16
We can then import and use our new button like this (listing 1.6).
Next, we will go through the fundamentals of what a component is, how they fit into the
workflow, as well as common use cases and design patterns for building them.
This component simply outputs ‘Hello World’ to the screen. Now, let’s look at how we can build
this basic component. The only out of the box components we will be using to build this
custom component are the View and Text elements we discussed earlier. Remember, a <View>
component is similar to an html <div>, and a <Text> component is similar to an html <span>.
Let’s take a look at a few ways that you can create a component.
This is the way to create a React Native component using es5 syntax. While you will probably
still see this syntax in use a lot on the web and in some older documentation, this syntax is
not being used as much in newer documentation and most of the community seems to be
heading to using the es2015 class syntax. Because of this, we will be focusing on the ES2015
class syntax for most of the rest of the book.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
17
The entire application does not have to be consistent in its component definitions, but it is usually
recommended that you do try to stay mostly consistent with either one or the other.
Another way to create React Native components is using ES2015 classes. This is the way we
will be creating our stateful components for the rest of the book and is now the recommended
way to do so by the community and creators of React Native, though we will be using stateless
components whenever we can.
import React from ‘react’
import {View,Text} from ‘react-native’
Since the release of React 0.14, we have had the ability to create what are called stateless or
reusable components. We have yet dived into state, but just remember that these
components are basically pure functions of their props, and do not contain their own state, so
their state cannot be mutated. This syntax is much cleaner than the class or createClass
syntax.
import React from 'react'
import {View,Text} from 'react-native'
or
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
18
function MyComponent () {
return <Text>HELLO FROM STATELESS</Text>
}
4. CREATEELEMENT (JAVASCRIPT)
React.createElement is rarely used, and you will probably never need to create a React
Native element using this syntax, but may come in handy if you ever need more control over
how you are creating your component or you are reading someone else’s code. It will also give
you a look at how JavaScript compiles JSX.
As you can see below, we pass in a View as the first argument to the first instance of
React.createElement, an empty object as the second argument, and another element as the
last argument.
In the second instance, we pass in Text as the first argument, an empty object as the
second argument, and “Hello” as the final argument.
class MyComponent extends React.Component {
render() {
return (
React.createElement(View, {},
React.createElement(Text, {}, "Hello")
)
)
}
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
19
Let’s go over all of the different pieces that make up the above component, and discuss what’s
going on.
IMPORTING
Here, we are importing React directly from the React library, and importing Component using
ES6 object destructuring from the React library. We are also using ES6 object destructuring
and an import statement to pull Text, and View into our file.
The import statement using ES5 would look like this:
varReact = require(‘react’)
The above statement without object destructuring would look like this:
import React = from 'react'
constComponent = React.Component
import ReactNative from 'react-native'
constText = ReactNative.Text
constView = ReactNative.View
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
20
The import statement is used to import functions, objects, or variables that have been
exported from another module, file, or script.
COMPONENT DECLARATION
Here we are creating a new instance of a React Native Component class by extending it, and
naming it Home. As you can see, before we declared React.Component, we are now just
declaring Component. This is because we have imported the Component element in the object
destructuring statement, giving us access to Component as opposed to having to call
React.Component.
The code for the component gets executed in the render method, and the content after the
return statement returns what is rendered on the screen. When the render method is called,
it should return a single child element. Any variables or functions declared outside of the
render function can be executed here. If you need to do any calculations, declare any
variables using state or props, or run any functions that do not manipulate the state of the
component, you can do so here in between the render() method and the return statement.
EXPORTS
Here, we export the component to be used elsewhere in our application. If you want to use
the component in the same file, you do not need to export it. After it is declared, you can use
it in your file, or export it to be used in another file. You may also use module.exports =
‘Home’ which would be es5 syntax.
export default Home
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
21
Text,
View
} from 'react-native'
</View>)
}
}
In the same file, below the Home class declaration, let’s start by building out a Header
component:
class Header extends Component {
render() {
return <View>
<Text>HEADER</Text>
</View>
}
}
This looks nice, but let’s rewrite the Header into a stateless component. We will discuss when
and why it is good to use a stateless component versus a regular React Native class in depth
later in the book. As you will begin to see, the syntax and code is much cleaner when we use
stateless components:
const Header =() => (
<View>
<Text>HEADER</Text>
</View>
)
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
22
constMain=() => (
<View>
<Text>Main</Text>
</View>
)
As you can see, the code we just wrote is extremely declarative, meaning it’s written in such a
way that it describes what you want to do, and is easy to understand in isolation.
This is a very high level overview of how we will be creating our components and views in
React Native, but should give you a very good idea of how the basics work.
After React Native is installed on your machine, you can initialize a new project by typing
react-native init followed by the project name:
react-native init myProject
• android – This folder contains all of the android platform specific code and
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
23
dependencies. You will not need to go into this folder unless you are either
implementing a custom bridge into android, or if you install a plugin that calls for some
type of deep configuration
• ios - This folder contains all of the ios platform specific code and dependencies. You will
not need to go into this folder unless you are either implementing a custom bridge into
android, or if you install a plugin that calls for some type of deep configuration
• node_modules – React Native uses something called npm (node package manager) to
manage dependencies. These dependencies are identified and versioned in the
.package.json file, and stored in the node_modules folder. When you install any new
packages from the npm / node ecosystem, they will go in here
• .flowconfig – Flow (also open sourced by Facebook) offers type checking for JavaScript.
Flow is similar to Typescript, if you are familiar with that. This file is the configuration
for flow, if you choose to use it.
• .gitignore – This is the place to store any file paths that you do not want in version
control
• .watchmanconfig – Watchman is a file watcher that React Native uses to watch files
and record when they change. This is the configuration for Watchman. No changes to
this will be needed except for rare use cases.
• .index.android.js- this is the entry point for the Android build of the application. When
you run your Android application, this is the first JavaScript file to get executed.
• .index.ios.js- This is the entry point for the iOS build of the application. When you run
your iOS application, this is the first JavaScript file to get executed.
• .package.json- This file holds all of our npm configuration. When we npm install files,
we can save them here as dependencies. We can also set up scripts to run different
tasks.
Now, let’s take a look at one of the index files. Open either index.ios.js or index.android.js:
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
24
As you can see, the above codelooks very similar to what we went over in the last section.
There are a couple of new items we have not yet seen:
StyleSheet
AppRegistry
StyleSheet is an abstraction similar to CSS stylesheets. In React Native you can declare
styles either inline or using Stylesheets. As you can see in the first view, there is a container
style declared:
<View style={styles.container}>
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
25
This is the JavaScript entry point to running all React Native apps. In the index file is the only
place you will be calling this function. The root component of the app should register itself with
AppRegistry.registerComponent(). The native system can then load the bundle for the app
and then actually run the app when it is ready.
Now that we have gone over what is in the file, let’s run the project in either our iOS
simulator or our Android emulator.
Figure 1.5 React Native starter project – what you should see after running the starter project on the emulator.
In the Text element that contains ‘Welcome to React Native’, replace that with ‘Welcome to
Hello World!’ or some text of your choice. Refresh the screen. You should see your changes.
1.8 Summary
• React Native is a framework for building native mobile apps in JavaScript using the
React JavaScript library.
• Some of React Native’s strengths are its performance, developer experience, ability to
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
26
build cross platform with a single language, one-way data flow, and community. You
may consider React Native over hybrid mainly because of its performance, and over
Native mainly because of the developer experience and cross platform ability with a
single language.
• JSX is a preprocessor step that adds an XML like syntax to JavaScript. You can use JSX
to create a UI in React Native.
• Components are the fundamental building blocks in React Native. They can vary in
functionality and type. You can create custom components to implement common
design elements.
• Components can be created using either the ES2015 (class definition) syntax or the
ES5 (createClass) syntax, with the es2015 (class definition) syntax being widely
recommended and used by the community and in newer documentation.
• Stateless components can be created with less boilerplate for components that do not
need to keep up with their own state.
• Larger components can be created by combining smaller subcomponents together.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
27
2
Understanding React
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
28
2.1 State
State and props are the way that data is handled and passed down in a React or React Native
application. First, we will look at state, and then props.
Props State
2.1.1 STATE
State is a collection of values that a component manages. React thinks of UIS as simple state
machines. When the state of a component changes, React rerenders the component. If any
child components are inheriting this state as props, then all of the child components get
rerendered as well.
When building an application using React Native, understanding how state works is
fundamental because state determines how stateful components render and behave. state
also is what allows us to create components that are dynamic and interactive. The main point
to understand when differentiating between state and props is that state is mutable, while
props are immutable.
State is initialized when the component is created, either in the getInitialState function
(React.createClass) or the constructor (ES2015 class). Once the state is initialized, it is then
available in the component as this.state.
The getInitialState function is invoked once before the component is mounted (listing
2.1). The returned value will be used as the state value. getInitialState will only work
when a component is instantiated with React.createClass, and not when using a
constructor. This is one of the React lifecycle methods. We will learn more about component
lifecycle methods and what it means for the component to be mounted in the next section, but
for now just understand that this function is called right before the component is created.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
29
The constructor function is called the moment that a JavaScript class is instantiated (listing
2.2). This is not a React lifecycle method, but a regular JavaScript class method.
The constructor takes the place of the getInitialState method when defining the initial state in
a React component when defined as a class.
UPDATING STATE
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
30
• replaceState will remove the entire previous state and replace it with whatever is
provided.
setState will be used unless there is an extreme circumstance where some keys need to be
removed from the state. We will not even go into an example of replaceState as the method is
not available on ES6 classes and will probably be removed entirely in a future version of
React, but it is worth knowing that it exists.
Let’s look at how to use setState (listing 2.3). To do so, we will introduce a new method, a
touch handler called onPress. onPress can be called on a few types of ‘tappable’ React Native
components, but here we will be attaching it to a Text component to get us started with this
basic example. We will be calling a function called updateYear when the Text component is
pressed that will update our state with setState. This function will be defined before our render
function, as it is usually best practice to define any custom methods before the render
method, but keep in mind that the order of the definition of the functions does not affect the
actual functionality.
Every time setState is called, React will rerender the component (calling the render method
again), and any child components. Calling this.setState is the way to change a state
variable and trigger the render method again, as changing the state variable directly will not
trigger a rerender of the component and therefore no changes will be visible in the UI. A
common mistake for beginners is updating the state variable directly. For example, something
like what we are doing in listing 2.4 does not work when trying to update state. The state
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
31
object is updated, but the UI is not updated because setState was not called, and the
component does not get rerendered.
However, there is a method that is available in React that can force an update once a state
variable has been changed as we did above. This method is called forceUpdate(listing 2.5).
Calling forceUpdate will cause render() to be called on the component, therefore triggering a
rerendering of the UI.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
32
Now that we have gone over how to work with state using a basic string, let’s look at a few
other data types. We will attach a Boolean, array, and object to our state and use it in our
component. We will also conditionally show a component based on a Boolean in our state
(listing 2.6).
2.2 Props
props (short for properties) are a component’s inherited values or properties that have been
passed down from a parent component. props are immutable, and can only be changed by
changing the initial values at the top level where they are declared and passed down. props
can be either static or dynamic values when they are declared, but when they are inherited
they are immutable. React’s Thinking in React documentation says that props are best
explained as “a way of passing data from parent to child.”
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
33
A good way to explain how props work is to simply show an example. In listing 2.7, we will
declare a book value and pass it down to a child component as a static prop.
As you can see, we’ve created two components: <MyComponent /> and <BookDisplay />.
When we use <BookDisplay />, we have passed in a property called book, and set it to a
string “React Native in Action”. Anything passed as a property in this way is available on the
child component as this.props.
You can also pass static properties like you would a dynamic variable, by using curly
braces and a string value (listing 2.8).
DYNAMIC PROPS
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
34
In our render method, before the return statement, let’s declare a variable “book” and
pass that variable in as a prop (listing 2.9).
Now, let’s pass a dynamic property to our component using state (listing 2.10).
Next, let’s look at how we may go about updating the state and therefore the prop that is
passed down. Remember, props are immutable, so we will be changing the state of the parent
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
35
component, which will update the props and trigger a rerender of both the component and the
child component.
Now, let’s break this idea up into individual parts and identify what needs to be done:
this.state = {
book: ‘React Native in Action’
}
updateBook() {
this.setState({
book: ‘Express in Action’
})
}
3. Pass the function and the state down to child component as prop
<BookDisplay
updateBook={ () => this.updateBook() }
book={ this.state.book } />
Ok, now that we know the pieces we need, let’s write all of the code to put this into action. We
will be using the components that we used in the previous examples, and adding the
additional functionality there (listing 2.11).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
36
Constantly referring to state and props as this.state and this.props can get repetitive,
violating the dry (don’t repeat yourself) principle that many of us try to follow. To fix this, you
may try using destructuring here, the same way as we have been doing when we declare our
React components. Let’s write a component using destructuring (listing 2.12).
As you can see, we are now not having to refer to this.state or this.props in our actual
component when referencing our book, instead we have taken the book variable out of our
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
37
state and our props and can reference the variable itself, which also looks a lot cleaner. This
starts to make a lot more sense and will keep your code cleaner as your state and props get
larger and more complex.
You can also destructure props in the function argument (listing 2.14).
As you can see, that looks a lot nicer and cleans up a lot of unnecessary code! We will be
using stateless components wherever we can, simplifying our code base and our logic.
Other data types work exactly as you might expect. For example, if you would like to pass an
array, you simply pass in the array as a prop. If you would like to pass an object, you would
simply pass in the object as a prop. Let’s look at a basic example (listing 2.15).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
38
render() {
return (
<BookDisplay
leapYear={ this.state.leapYear }
info={ this.state.info }
topics={[‘React’, ‘React’, ‘JavaScript’]] />
)
}
}
if(props.leapYear) {
leapyear = <Text>This is a leapyear!</Text>
}
return (
<View>
{ leapyear }
<Text>Book type: { info.type }</Text>
{ topics }
</View>
)
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
39
First, we will go over the basics of the component specifications. The component
spefication basically lays out how your component should react to different things happening
in the lifecycle of the component. See figure 2.16 for a list of these specifications. We will then
break this apart and go into detail of what each one means and how they are used so you will
have a clear understanding of what this all means.
2.3.1 render
The render method (figure 2.17) is the only method in the component specification required
when creating a component, and must return either a single child element, null, or false. This
child element can either be component that you have declared yourself, (such as a <View />
or <Text />), or another component that you have defined.
You can use the render method with or without parenthesis. If you don’t use parenthesis, then
the returned element must of course be on the same line as the return statement, as shown in
listing 2.18.
The render method can also return another component that was defined elsewhere, as shown
in listing 2.19.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
40
You can also check for conditionals in the render method, perform logic, and return
components based on their value, as shown in listing 2.20.
Use a constructor method (listing 2.22)to set the initial state when using classes. The
concept of classes, as well as the constructor function, is not specific to React or React Native;
it’s an ES2015 specification and is really just syntactic sugar on top of JavaScript’s existing
prototype based inheritance for creating and initializing an object created with a class. Other
properties can also be set for a component class in the constructor by declaring them with the
syntax this.property (property being the name of the property).The keyword this refers
to the current class we are in.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
41
someOtherBoolean: true
}
this.name = 'Hello World'
this.type = 'class'
this.loaded = false
}
When using a constructor, you must use the super keyword before you can use the this
keyword. Also, if you need access to any props passed to the component, they must be
passed as an argument to the constructor and the super call. Setting the state based on props
is usually not good practice unless you are intentionally setting some type of seed data for the
component’s internal functionality, as the data is no longer going to be consistent across
components if it is changed. This is because getInitialState is only invoked when the
component is first mounted or created, and not again. This means that if you rerender the
same component using a different new value as a prop, this already mounted component and
any children inheriting this data as props will not receive this new data (listing 2.23).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
42
}
},
render() {
return (
<View>
<Text>{ this.props.firstName }</Text>
<Text>{ this.props.lastName }</Text>
<Text>{ this.props.favoriteColor }</Text>
</View>
)
}
})
defaultProps (ES2015 class syntax) Setting default props when using classes is a little
different. defaultProps are defined as properties on the component instead of inside the class
body, as shown in listing 2.25.
ChildComponent.defaultProps = {
firstName: ‘Nader’,
favoriteColor: ‘blue’
}
defaultProps can also be set as a property on a stateless component, just like we did with
the ES2015 classes, as shown in listing 2.26.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
43
ChildComponent.defaultProps = {
firstName: ‘Nader’,
lastName: ‘Dabit’,
favoriteColor: ‘blue’
}
2.3.4 propTypes
Sometimes, you need to ensure that a certain type of prop is passed into your component and
whether or not the prop is required. To do this, you can set a propTypes object, and check to
make sure certain props are passed in, then specifying if they are required. If the props are
not passed in and they are required, a warning will be shown in the JavaScript console. You
will also get a warning if the incorrect type of prop is passed in. There are two ways to set this
up depending on whether you are using React.createClass syntax or class syntax. Let’s look
at how to set this up (listing 2.27).
render() {
return (
<View>
<Text>Name: {this.props.firstName}</Text>
<Text>Fav language: {this.props.favoriteLanguages[0]}</Text>
<Text>Age: {this.props.about.age}</Text>
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
44
</View>
)
}
})
ChildComponent.propTypes = {
firstName: React.PropTypes.string,
favoriteLanguages: React.PropTypes.array,
about: React.PropTypes.object
}
You can also use propTypes with stateless component by defining propTypes as a property of
the component (listing 2.29).
If any of the props that are specified are not passed into the component, a warning will be
shown in the JavaScript console.
Some props may need to be required for the component to function correctly. This can be
solved with the .isRequired property. To require a prop, simply add .isRequired at the end
of the propType (listing 2.30).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
45
You can take arrays and objects one step further by specifying what type of values should
be in the object or array(listing 2.31).
See listing 2.32 for a list of the propTypes that can be used
React.PropTypes.arrayOf(React.PropTypes.number),
React.PropTypes.objectOf(React.PropTypes.number),
2.3.5 statics
statics statics allow you to define static methods that can be called on the component class.
Static methods can be run before component instances are created, but do not have access to
the props or state of the component.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
46
There are two ways to define static methods or properties on a component, depending on
whether you are using class syntax or React.createClass syntax.
When using React.createClass, you declare a statics object and define the static
methods in this object (listing 2.33).
statics: {
sayHello() {
console.log(‘Hello’)
}
},
render() {
return (
<SomeComponent />
)
}
})
MainComponent.sayHello()
When using ES2015 classes, you declare statics as a static class method (listing 2.34).
render() {
return (
<SomeComponent />
)
}
}
MainComponent.sayHello()
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
47
2.4.1 ComponentWillMount
componentWillMount (listing 2.35)is invoked only once and is done so immediately before the
initial rendering of the component occurs. This happens before the render() method is called.
At this point the component does not have any access to the UI, and you will also not have
any access to child refs as they have not yet been created. In listing 2.35, we set the state
with an initial value of 0, and we log out both the state and the refs in the render method. The
first values logged out for tick is 1 and the refs as an empty object, showing us that the
render method runs only after componentWillMount, but after componentDidMount.
Listing 2.35componentWillMount
class MainComponent extends Component {
constructor() {
super()
this.state = { tick: 0 }
}
componentWillMount() {
this.setState({
tick: this.state.tick + 1
})
}
componentDidMount () {
this.setState({
tick: this.state.tick + 1
})
}
render() {
console.log('state:', this.state)
console.log('refs:', this.refs)
debugger
return <div />
}
}
2.4.2 componentDidMount
componentDidMount (listing 2.36)is called exactly once, just after the component has
been loaded.
This method is a good place to fetch data with ajax calls, perform setTimeout functions, or
integrate with other JavaScript frameworks.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
48
componentDidMount() {
// simulate ajax call
setTimeout(() => {
this.setState({
loading: false,
data: {name: ‘Nader Dabit’, age: 35}
})
}, 2000)
}
render() {
if(this.state.loading) {
return <Text>Loading</Text>
}
const { name, age } = this.state.data
return (
<View>
<Text>Name: {name}</Text>
<Text>Age: {age}</Text>
</View>
)
}
}
2.4.3 componentWillReceiveProps
componentWillReceiveProps (listing 2.37) is invoked when a component is receiving new
props, and is not called for the initial render. This method enables you to update the state
depending on the existing and upcoming props, without triggering another render. A use case
for this could be checking a prop change, and setting state based on the value of the new prop
vs the existing prop.
componentWillReceiveProps(nextProps) {
if(nextProps.name != this.props.name) {
this.setState({ nameChanged: true })
}
}
render() {
return (
<View>
<Text>
{ this.props.name }
</Text>
{ this.state.nameChanged &&<Text>Name has changed</Text> }
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
49
</View>
)
}
}
2.4.4 shouldComponentUpdate
shouldComponentUpdate (listing 2.38) returns a Boolean, and allows you to decide exactly
when a component renders. If you know that the new state or props will not require the
component or any of its children to render, you can return false. If you want the component to
rerender, return true.
shouldComponentUpdate(nextProps, nextState) {
if(nextProps.name !== this.props.name) {
return true
}
return false
}
render() {
return <SomeComponent />
}
}
2.4.5 componentWillUpdate
componentWillUpdate(listing 2.39) is invoked immediately before rendering when new props
or state are being received. This method is not called for the initial render, and is an
opportunity to perform preparation before a render occurs. Here, you can directly manipulate
the state of the component without calling this.setState. Also note that you cannot call
setState in this method.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
50
2.4.6 componentDidUpdate
componentDidUpdate(listing 2.40) is invoked immediately after the component has been
updated and rerendered. You get the previous state and previous props as arguments.
2.4.7 componentWillUnmount
componentWillUnmount (listing 2.41) is called before the component is removed from the
application. Here, you can perform any necessary cleanup, remove listeners, or remove timers
that were set up in componentDidMount.
handleClick() {
this._timeout = setTimeout(() => {
this.openWidget();
}, 2000);
}
componentWillUnmount() {
clearTimeout(this._timeout);
}
render() {
return <SomeComponent
handleClick={() => this.handleClick()} />
}
}
2.5 Summary
• State is a way to handle data in React components and updating state rerenders the UI
of the component and any child component relying on this data as props.
• Props are how data is passed down through a React Native application to child
components and that updating props automatically updates any components receiving
the same props.
• The React Component Specification is a group of methods and properties in a React
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
51
component that specifies the declaration of the component. render is the only required
method when creating a React component, with all other methods and properties being
optional.
• React Lifecycle methods are a group of methods available in a React component that
are executed at specific points in a component's lifecycle and control how the
component functions and updates.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
52
3
Building Your First
React Native App
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
53
As we did in chapter one, let’s now visually break this up into components and container
components.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
54
Now let’s take a look at how this would look in our app, using React Native components by
laying out a basic implementation of these components as shown in listing 3.1.
Our app will start off displaying a heading, tab bar, text input and a button. When we add a
Todo to our app, it will add the Todo to our array of Todos and display the new Todo beneath
the input. Each Todo will have two buttons: Done and Delete. Our Done button will mark it as
complete, and the Delete button will remove it from the array of Todos.
At the bottom of the screen, the TabBar that will filter the Todos based on whether they
are complete or still active.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
55
Let’s get started coding the app. To begin, create a new React Native project by typing
react-native init TodoApp (or, instead of TodoApp whatever you would like your app to be
named)in our terminal (figure 3.3).
REACT NATIVE VERSIONI am using React Native version 0.33 for this example. Newer versions may
have api changes, but nothing should be breaking for building our Todo app. You are welcome to use either the
most recent version of React Native, or use the specific version I am using here.
Now, go into your index file. If you are developing for iOS, open index.iOS.js, and if
developing for Android open index.Android.js. The code for both platforms will be exactly the
same.
Here, we’re only bringing in AppRegistry from react-native. We’re also bringing in our main
App component, which we will create next.
In the AppRegistry method, we’re initiating our application. AppRegistry is the JS entry
point to running all React Native apps. Appregistry takes two arguments. The first argument
is the appKey, or the name of the actual application which we defined when we initialized the
app. The second argument is a function that returns the React Native component we would
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
56
like to use as the entry point of our app. In this case, we are returning the TodoApp
component we declared in Listing 3.2
Now, create a folder in the root of the application called app. In the app folder, create a file
called App.js. In it, let’s add some basic code to get us started (listing 3.3).
We’ve pulled in a new component called ScrollView, which wraps the platform ScrollView
and is basically a scrollable View component. We make sure that both the ScrollView and the
parent View of the ScrollView both have a flex:1 value. flex:1which will make the
component fill the entire space of it’s parent container.
Now, let’s go ahead and set up an initial state for some of the values we will be needing
later on. We will be needing an array to keep our todos that we will name todos, a value to
hold the current state of the TextInput that will be adding the todos which we will name
inputValue, and a value to store the type of todo that we are currently viewing (All, Current,
or Active) which we will name type.
In App, before our render function, let’s add a constructor and an initial state to the class
and initialize these values in our state (listing 3.4).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
57
...
Next, let’s go ahead and create our Heading component and give it some styling. In the app
folder, create a file called Heading.js. This will be a stateless component (listing 3.5).
Note that in the styling of headerText, we are passing an rgba value to color. If you are not
familiar with rgba, the first three values make up the rgb color values, and the last value
represents the alpha or the opacity (red, blue, green, alpha). We are passing in an alpha value
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
58
of 0.25, or 25%. We are also setting the font weight to be ‘100’, which will give our text a
thinner weight and look.
Go back into App.js and bring in the Header component and place it in the ScrollView,
replacing the empty View we originally placed there (listing 3.6).
...
Let’s go ahead and run our app to see our new Heading and App Layout. This is how our
application should now look (figure 3.4).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
59
Next, let’s go ahead and create our TextInput component and give it some styling. In the app
folder, create a file called Input.js (listing 3.7).
conststyles = StyleSheet.create({
inputContainer: {
marginLeft: 20,
marginRight: 20,
shadowOpacity: 0.2,
shadowRadius: 3,
shadowColor: '#000000',
shadowOffset: { width: 2, height: 2 }
},
input: {
height: 60,
backgroundColor: '#ffffff',
paddingLeft: 10,
paddingRight: 10
}
})
We are using a new React Native component called TextInput here. If you are familiar with
web development, this is very similar to an html input. We are also giving both the
TextInput and the outer View their own styling.
TextInput takes a few other props. Here, we are specifying a placeholder to show text
before the user starts to type, a placeholderTextColor which will style the placeholder text,
and a selectionColor which styles the cursor for the TextInput.
Next, let’s wire up a function that will let us get the value of the TextInput and save it to
the state of our App component. To do this, first go into App.js and add a new function called
inputChange below the constructor and above the render function. This function will update
the state value of inputValue with the value passed in, and for now will also log out the value
of inputValue for us to make sure the function is working.
To view console.log() statements in React Native, we first need to open the developer
menu. Let’s go ahead and take a look at the developer menu and see how it works.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
60
If you are not interested in the Developer Menu or want to skip this section for now, go to section 2.1.6 to
continue building out the Todo app.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
61
If cmd + d or cmd + ctrl + zdo not open the menu for you, you may need to connect your hardware to
the keyboard. To do this, go to Hardware -> Keyboard -> Connect Hardware Keyboard in your simulator menu,
as shown in figure 3.7.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
62
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
63
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
64
1. Reload (iOS) / Reload JS (Android) - Simply reloads the app. This can also be done
by pressing cmd + r on the keyboard (iOS) or pressing r twice (Android)
2. Debug JS Remotely (iOS and Android) - This opens the chrome dev tools and allows
you to have full debugging support through the browser. Here, you have access not
only to logging statements within your code, but also to break points and whatever you
are used to while debugging web apps with the exception of the DOM (figure 3.6). If
you need to log out any information or data in your app, this is usually the place to do
so.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
65
3. Enable Live Reload (iOS and Android) - This will enable live reload. When you
make changes in your code, the entire app will reload and refresh in the simulator
4. Start Systrace (iOS only) - Systrace is a profiling tool. This will give you a good idea
of where your time is being spent during each 16ms frame while your app is running.
Profiled code blocks are surrounded by markers start/end markers which are then
visualized in a colorful chart format.To use this, you need to install trace2html by
typing brew install trace2html into your terminal window.
Systrace can also be enabled manually from the command line in Android. If you would
like to learn more about this, check out the docs for a very comprehensive overview.
If your trace .html file isn't opening correctly, check your browser console for the
following:
Because Object.observe was deprecated in recent browsers, you may have to open the
file from the Google Chrome Tracing tool. You can do so by:
1. Opening tab in chrome chrome://tracing
2. Selecting load
3. Selecting the html file generated from the previous command.
5. Enable hot reloading (iOS and Android) - This is a really great feature that was
added in version .22 of React Native. It offers an amazing developer experience, giving
you the ability to see your changes immediately as your files are changed without
losing the current state of the app. This is expecially useful when making ui changes
deep within your app without losing state. This is different than live reloading as it
actually retains the current state of your app, only updating the components / state
that has been changed, while the live reloading will reload the entire app therefore
losing the current state.
6. Show inspector (iOS and Android) - This will bring up a property inspector similar
to what you see in the chrome dev tools. You can click on an element and see where it
is in the heirarchy of components, as well as any styling applied to the element (figure
3.11).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
66
7. Show Perf Monitor (iOS and Android) – This brings up a small box in the top left
corner of your app giving you some information about the performance of your app.
Here you will see the amount of RAM being used, and the number of frames per second
that the app is currently running at. If you click the box, it will expand to show you
even more information about the app (figure 3.12).
8. Dev Settings (Android Emulator only) – Brings up additional debugging options,
includeing an easy way to toggle between __DEV__ environment variable being true /
false.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
67
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
68
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
69
inputChange will take one argument, the value of the TextInput, and the inputChange value in the
state to the value passed into the function.
Now, we need to wire the function up with our TextInputin the Input component. Open
Input.js, and update the TextInpt component with the newinputChange function and the
inputValue property (listing 3.9).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
70
)
...
We’ve destructured the propsinputValue and inputChange in the creation of the stateless
component. When the value of the TextInput changes, the inputChange function is called and
the value is passed to the parent component to set the state of inputValue. We’ve also set
the value of the textInput to be inputValue, so we can later control and reset the
TextInput.onChangeText is a method that will be called every time the value of the
TextInput component is changed, and will get passed the value of the TextInput.
Now, let’s run the project again and see how it looks (figure 3.14).
We’re logging the value of the input, so as you type you should see the value being logged out
to the console.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
71
Now that we have our inputValuevalue being stored in the state, let’s create a button to add
the items to a list of todos.
Before we create the button, let’s create a function that we will bind to our button that will
add the new todo to our array of todos that we have defined in our constructor.
We will call this function submitTodo. Let’s place it after our inputChange function and
before our render function (listing 3.10).
❶ First, we check to see if the inputValue is empty, if it is empty we return without doing anything else.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
72
❷ If inputValue is not empty, we then create and then assign a todo variable an object, we give this object a
title, a todoIndex, and a completeboolean (the todoIndex has not yet been created, we will do so shortly).
❸ After we create our todo variable, we increment the todoIndex.
❹ We then push the new todo to the existing array of todos.
❺ Finally, we set the state of our todos to match the updated array of this.state.todos, and reset the
inputValue to an empty string.
❻ We also log out the state to make sure that everything is working. This is done in a callback function from
setState. Once the state is set, you have the option to pass a callback function and that is what we are doing
here.
Now, let’s create the todoIndex at the top of our App.js file, below our last import statement
(listing 3.11).
let todoIndex = 0
Now that our submitTodo function has been created, let’s create a file called Button.js and
wire up this function to work with the button (listing 3.12).
conststyles = StyleSheet.create({
buttonContainer: {
alignItems: 'flex-end'
},
button: {
height: 50,
paddingLeft: 20,
paddingRight: 20,
backgroundColor: '#ffffff',
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
73
width: 200,
marginRight: 20,
marginTop: 15,
borderWidth: 1,
borderColor: 'rgba(0,0,0,.1)',
justifyContent: 'center',
alignItems: 'center'
},
submit: {
color: '#666666',
fontWeight: '600'
}
})
In the above component, we are using TouchableHighlight for the first time.
TouchableHighlight is one of the ways you can create buttons in React Native and is
fundamentally comparable to the html button element.
With TouchableHighlight, we can wrap views and make them respond properly to touch
events. On press down, the default backgroundColor is replaced with a specified
underlayColor property that we will provide as a prop. As you can see, we have specified an
underlayColor of '#efefef' which is a light gray, while the background color is white. This
will give the user a good sense of whether or not the touch event has registered. If no
underlayColor is defined, it defaults to black.
TouchableHighlight only supports one main child component. As you can see, we are
passing in a Text component. If you would like multiple components to be within a
TouchableHighlight, simply wrap them in a single View and pass this View as the child of the
TouchableHighlight.
We also have quite a bit of styling going on.
Do not worry about styling specifics in this chapter as we will cover them in depth in the coming chapters, but
do take a look at them and see what we are doing to get an idea of how styling works in each component. This
will help out a lot once we start going in depth in the future as you will already be exposed to some styling
properties and how they work.
Now that the Button component is created and wired up with the function we defined in
App.js, let’s bring this component into our app and see if it works! Open app/App.js (listing
3.13).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
74
consttodoIndex = 0
...
constructor() {
super()
this.state = {
inputValue: '',
todos: [],
type: 'All'
}
this.submitTodo = this.submitTodo.bind(this) ❸
}
...
render () {
let { inputValue } = this.state
return (
<View style={styles.container}>
<ScrollView style={styles.content}>
<Heading />
<Input
inputValue={inputValue}
inputChange={(text) => this.inputChange(text)} />
<Button submitTodo={this.submitTodo} /> ❷
</ScrollView>
</View>
)
}
We’ve imported the Button component, and then placed it under the Input component within
our render function. submitTodo is passed into the Button as a property, which will
callthis.submitTodo.
Now, refresh the app. It should look like figure 3.16.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
75
When we add a todo, the TextInput should clear and the app state should log out to the
console, showing an array of todos with the new todo in the array.
Now that we are adding todos to our array of todos, we need to render these todos to the
screen. To get started with this, we need to create 2 new components: TodoList and Todo.
TodoList will render our list of Todos, and will use theTodo component for each individual
todo.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
76
conststyles = StyleSheet.create({
todoContainer: {
marginLeft: 20,
marginRight: 20,
backgroundColor: '#ffffff',
borderTopWidth: 1,
borderRightWidth: 1,
borderLeftWidth: 1,
borderColor: '#ededed',
paddingLeft: 14,
paddingTop: 7,
paddingBottom: 7,
shadowOpacity: 0.2,
shadowRadius: 3,
shadowColor: '#000000',
shadowOffset: { width: 2, height: 2 },
flexDirection: 'row',
alignItems: 'center'
},
todoText: {
fontSize: 17
}
})
The Todo component takes one property for now, a todo, and renders the title within a Text
component. We have also added styling to the View and Text component we are using here.
Now that we have created our Todo component, let’s create our TodoList component
(listing 3.15).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
77
<Todo
key={i}
todo={todo} />
)
})
return (
<View>
{todos}
</View>
)
}
Our TodoList component will take one property for now, an array of todos. We then map over
these todos and create a new Todocomponent (which we imported at the top of the file) for
each todo, passing in the todo as a property to the Todo component. We have also specified a
key, and passed in the index (i) as a key to each component.
Now that this is set up, the last thing we need to do is import the TodoList component
into our App.js file, and pass in the todos as a property (listing 3.16).
Let’s run the app. When we add a todo, we should see it pop up in our list of todos (figure
3.18).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
78
Ok, now that we have this working, the next step will be for us to mark a todo as complete,
and to delete a todo. Let’s open App.js and create a toggleComplete and deleteTodo function
below our submitTodo function (listing 3.17).
toggleComplete will toggle whether or not the todo is complete, and deleteTodo will
delete the todo.
toggleComplete (todoIndex) { ❹
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
79
To hook these in, we need to create a button component we will pass in to the todo. Let’s go
into our app folder and create a new file called TodoButton.js (listing 3.18).
conststyles = StyleSheet.create({
button: {
alignSelf: 'flex-end',
padding: 7,
borderColor: '#ededed',
borderWidth: 1,
borderRadius: 4,
marginRight: 5
},
text: {
color: '#666666'
},
complete: {
color: 'green',
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
80
fontWeight: 'bold'
},
deleteButton: {
color: 'rgba(175, 47, 47, 1)'
}
})
export default TodoButtton
Now, let’s pass our new functions down as props to the TodoList component (listing 3.19).
And then we pass toggleComplete and deleteTodo as props to the Todo component (listing
3.20).
Finally, open Todo.js and update theTodo component to bring in the new TodoButton
component and some styling for the button container (listing 3.21).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
81
<View style={styles.todoContainer}>
<Text style={styles.todoText}>
{todo.title}
</Text>
<View style={styles.buttons}>
<TodoButton
name='Done'
complete={todo.complete}
onPress={() =>toggleComplete(todo.todoIndex)} />
<TodoButton
name='Delete'
onPress={() =>deleteTodo(todo.todoIndex)}/>
</View>
</View>
)
conststyles = StyleSheet.create({
...
buttons: {
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center'
},
...
)}
We’ve added two TodoButtons, one with the name Done and one with the name Delete. We
have also passed down toggleComplete and deleteTodo as functions to be called as the
onPress we defined in TodoButton.js. If we refresh our app and add a todo, we should now
see our new buttons.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
82
If we click done, the button text should now be bold and green. If we click delete, the todo
should disappear from our list of todos.
We are now almost done with the app. The final step is to build a tab bar filter that will
show us either all of our todos, only our complete todos, or only our incomplete todos. To get
this started, let’s create a new function that will set the type of todos that we will show.
In our constructor, we set a type variable to ‘All’ when we first created the app. We will
now create a function named setType that will take in a type as an argument and update the
type in our state. Place this function below the toggleComplete function (listing 3.22).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
83
Now, we need to create the TabBar and TabBarItem components. First, let’s go ahead and
create the TabBar component. Create a file in the app folder named TabBar.js (listing 3.23).
conststyles = StyleSheet.create({
container: {
height: 70,
flexDirection: 'row',
borderTopWidth: 1,
borderTopColor: '#dddddd'
}
})
This component will take two props: setType and type which will both be passed down from
our main App component.
We are importing our yet to be defined TabBarItem component. Each TabBarItem
component takes three props: title, type, and setType. Two of the components also are
taking a border prop (boolean), which if set will add a left border style.
Next, create a file in the app folder named TabBarItem.js (listing 3.24).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
84
</TouchableHighlight>
)
conststyles = StyleSheet.create({
item: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
border: {
borderLeftWidth: 1,
borderLeftColor: '#dddddd'
},
itemText: {
color: '#777777',
fontSize: 16
},
selected: {
backgroundColor: '#ffffff'
},
bold: {
fontWeight: 'bold'
}
})
In the TouchableHighlight component, we are checking a few props and setting styles based
on the prop. If selected is true, we give it the style styles.selected. If border is true, we
give it the style styles.border. If type is equal to the title, we give it styles.selected.
In the Text component, we are also checking to see if type is equal to title, and if so we
add a bold style to it.
To implement the TabBar, let’s open app/App.js and bring in the TabBar component and
set it up. We will also bring in type to our render function as part of our destructuring of
this.state (listing 3.25).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
85
todos={todos} />
<Button submitTodo={() => this.submitTodo()} />
</ScrollView>
<TabBar type={type} setType={this.setType.bind(this)} />
</View>
)
}
...
Here, we bring in the TabBar component. We then destructure ‘type’ from our state, and pass
it not only to our new TabBar component, but also to our TodoList component. We will use
this ‘type’ variable in just a second when filtering our todos based on this type.
We also pass the setType function as a prop to the Tabbar component.
The last thing we need to do is open our TodoList component and add a filter to return
only the todos of the type we are currently wanting back based on the tab that is selected.
Open TodoList.js and destructure the type out of the props and add the following
getVisibleTodos function before the return statement (listing 3.26).
We are using a switch statement to check and see which type is currently set. If ‘All’ is set, we
return the entire list of todos. If 'Complete' is set, we filter the todos and only return the
complete todos. If ‘Active’ is set, we filter the todos and only return the incomplete todos.
We then set the todos variable as the returned value of getVisibleTodos.
Now we should be able to run the app and see our new TabBar. The TabBar should filter
based on which type is seleted:
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
86
3.2 Summary
In this chapter we learned:
• Using the JavaScript console is a good way to debug your app and log out useful
information.
• How to build a complete functioning app by building a todo app.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
87
4
Introduction to styling
• Styling overview
• Applying styles to View Components
• Applying styles to Text Components
Views are the main building block of a React Native UI, so it is important to go over and
explain all of the style properties that a View component can implement.
Next we will walk through styling Text components.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
88
The created styles are then available on the styles object (listing 4.4).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
89
In addition to applying predefined styles one at a time, you can also pass multiple styles in an
array (listing 4.5).
Remember when doing this, that the last style passed in will override the previous style if
there is a duplicate property. For example, in the above component, if we had the following
StyleSheet defined, the Text component would render red text even though Text was
originally set to a color of black (listing 4.6).
You can also pass in both inline styles and StyleSheet styles into an array. To do this, you
need to make sure that the inline styles are defined in a separate object (listing 4.7).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
90
BACKFACEVISIBILITY
The backfaceVisibility property dictates whether or not an element is visible when the
element is rotated more than 90 degrees. This property can be set to either 'visible' or
'hidden '.
This property is useful when transforming elements by rotating their position, or flipping
them backwards, and wanting to control whether or not they are still visible. For example, we
will take a View and rotate it 180 degrees, and see how this property works (listing 4.8).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
91
backfaceVisibility: 'visible',
transform: [{
rotateY: '180deg'
}]
}
})
If we changed backfaceVisibility to 'hidden', then you would not see the element at all.
If we did not set a property at all, which will be the case almost all of the time, then it would
still show, as backfaceVisibility defaults to 'visible'.
TRANSFORMS We have not yet covered transforms, so don’t worry about fully understanding them if you
have not worked with them before. We’ll be covering them in more depth later on in this chapter. If you have
worked with CSS transforms before, just remember that they are similar to those.
BACKGROUNDCOLOR
The backgroundColor property sets the background color of an element. This property takes a
string of one of the following properties. These same color properties are available anywhere
colors are used in a React Native application:
• rgb stand for red, green, and blue. The values for red, green, and blue may be
specified using a scale from 0–255. Higher numbers mean more of each color.
• alpha is similar to opacity (0 is transparent, 1 is solid)
'#06f'- #rgb
'#06fc'- #rgba
'#0066ff'- #rrggbb
'#0066ff00' - #rrggbb
'rgb(0, 102, 255)' - rgb(number, number, number)
'rgba(0, 102, 255, .5)' - rgb(number, number, number, alpha)
'hsl(216, 100%, 50%)' -hsl(hue, saturation, lightness)
'hsla(216, 100%, 50%, .5)' -hsl(hue, saturation, lightness, alpha)
'transparent' – transparent background
'dodgerblue' – any css3 specified named color (black, red, blue, etc...)
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
92
When working with backgroundColor, as with all styles, you can also use variables (listing
4.10).
*Above, we are using template literals to process our variables. Template literals were
introduced with the es2015 specification and are a great way to embed expressions into
strings. To use them, just add back ticks around the statement and wrap any variable or
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
93
expressions in a dollar sign and two curly braces (${someVariable}). The two following
expressions are exactly the same (listing 4.11).
BORDER PROPERTIES
There are quite a few border properties, and they all work together, so we will go over them
here all together:
• borderColor
• borderWidth
• borderStyle
• borderLeftColor
• borderLeftWidth
• borderBottomColor
• borderBottomLeftRadius
• borderBottomRightRadius
• borderTopLeftRadius
• borderTopRightRadius
• borderBottomWidth
• borderTopColor
• borderTopWidth
• borderRightColor
• borderRightWidth
To set a border, we must first set a borderWidth. The borderWidth is the size of the border,
and it will always be a number. This can be done in a few ways. We can either set a
borderWidth that applies to the entire component, or choose which borderWidth we would
like to set specifically. First, let’s set a borderWidth of 1 to a View element (listing 4.12).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
94
Notice that the border color defaults to black, and it is applied to the entire component on all
four sides. Let’s specify only a border left color and increase the width of the border so we can
see it better (listing 4.13).
Now, let’s declare a main borderColor property. Notice the results, specifically that the red
color (borderLeftColor) does not get overwritten even though we have it declared before the
green color (borderColor). This is because specificity takes precedence over generality
(listing 4.14).
...
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
95
Now, let’s see how the borderWidth property will respond with specificity. We’ll do this by
setting a borderTopWidth of 0 before we declare the borderWidth (listing 4.15).
As you can see, the borderTopWidth property also takes precedence over the borderWidth
property:
BORDERRADIUS
Now, let’s look at borderRadius. borderRadius will allow us to define how rounded border
corners are on our elements. Let’s use borderRadius to make our view into a circle. To do
this, we’ll be setting a width and height value on our View, and calculating our borderRadius
value as ½ of that value (listing 4.16).
* When specifying borderRadius without a position (for example, borderTopRadius), it
will set the radius to all 4 corners of the element.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
96
Notice that the Text element’s background is covering up the circle! This is because Text
elements will always inherit the background color of the parent element. Let’s fix this.
To do so, let’s set a backgroundColor of transparent to the parent View (listing 4.17).
...
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
97
The fact that that Text elements inherit their backgroundColor will definitely be something to
keep in mind when working with the borderRadius property, as most of the time there will be
a parent backgroundColor set somewhere in the app, and you will need to override it.
Now, let’s only set a borderBottomLeftRadius and borderBottomRightRadius (listing
4.18).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
98
BORDERSTYLE
borderStyle is the last of the border properties we have yet to cover. The borderStyle
property defaults to solid, which is what we have seen already. The other two options are
dotted and dashed. Let’s apply dashed to a View component and see how it looks (listing
4.19).
MARGIN
Next, let’s take a look at margin. margin defines how far away an element is to the previous
or parent component.
The margin properties available are
• margin
• marginLeft
• marginRight
• marginTop
• marginBottom
If only the general margin property is set without another more specific value such as
marginLeft or marginTop, then that value is passed to all sides of the component (top, right,
bottom, and left). If both margin and a more specific margin property are specified (for
example, marginLeft), then the more specific margin property takes precedence.
First, let’s look at how margin effects an element. If you are familiar with CSS, you will
notice the similarities.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
99
Now, let’s recreate marginLeft and marginRight functionality in a component (listing 4.20).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
100
PADDING
padding sets the space between the content of the element and the border of the same
element.
The available properties available for padding are:
• padding
• paddingLeft
• paddingRight
• paddingTop
• paddingBottom
If only the main padding property is set without another more specific value such as
paddingLeft or paddingTop, then that value is passed to all sides of the component (top,
right, bottom, and left). If both padding and a more specific padding property are specified,
for example, paddingLeft, then the more specific padding property takes precedence.
Let’s recreate similar design as above, this time using padding instead of margin. In figure
4.16, take a look at components A and B, with no padding.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
101
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
102
POSITION
position defines how the component should be laid out in relation to the other components
relative to it. The default position is 'relative '
The available properties available for position are:
• relative
• absolute
When using absolute positioning, the following properties are also available:
• top
• left
• bottom
• right
As stated above, relative is the default position of all elements. relative position states that
all items be laid out relative to the sibling or parent. This means that if there is a component
that has a height of 100 and a marginBottom of 20, then the next component will be 20 pixels
below the previous component. The only way to have two relative components overlap is to
apply a negative margin to one of them
With absolute positioning, the component will be positioned absolutely relative to the
parent, and whose margins relative to their parent can be controlled with top, bottom, left,
and right properties. What does this mean? Well, think of it like this: If we have three nested
components: A, B, and C, and give element C an absolute position, then C’s position will be
absolute relative to B, because B is the parent of C. If we want C to be positioned absolutely
relative to A, then we need to move C to be a child of A.
If what we just described doesn’t make sense, let’s take a look at this in action to give us a
clearer understanding of how absolute positioning works. We will have three components:
container, parent, and child. We will give child a position of ‘absolute’, left of 0, and bottom
of 0 and see how this looks, taking into consideration the styling that parent has (specifically
the paddingLeft property) (listing 4.22).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
103
width: 300,
height: 200,
backgroundColor: '#cccccc',
paddingLeft: 40
},
child: {
width: 150,
height: 150,
position: 'absolute',
backgroundColor: 'red',
bottom: 0,
left: 0
}
})
Notice that the paddingLeft had no effect on the element, and we were able to position the
element exactly where we wanted it by giving it a leftvalue of 0 and a bottom value of 0.
Also notice that the element is still within its parent, which is what we meant when we said
relative to its parent. It did not go to the bottom of the entire screen because it still has to
stay relative to its parent. Next, let’s take the child component out of the parent and place it
directly into the container, keeping the same styling (listing 4.23).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
104
Now that the child component is relative to the entire container, we see that it drops down to
the bottom left of the screen.
If you are looking to add a drop shadow to a View element, there are separate ways to do this
depending on what platform you are on.
If you are on Android, you use elevation which uses Android's underlying elevation API.
This adds a drop shadow to the item and affects z-order (z-index) for overlapping views.
If you are on iOS you use ShadowPropTypesIOS for drop shadows, which will only add a
shadow and will not affect the z-order.
The available properties available for ShadowPropTypesIOS are
• shadowColor
• shadowOffset
• shadowOpacity
• shadowRadius
• number(0 to infinity)
Let’s take the previous component we were using and add a drop shadow to the child using
elevation (Android only) (listing 4.24).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
105
As we stated earlier, elevationalso effects the z-index of the item. This means that if there
are two or more items occupying the same space, we can decide which one needs to be in
front by giving it the larger elevation and therefore the larger z-index.
Let’s see this in practice. To do so, we will create a View with three boxes, each of which
are positioned absolutely. We will give them three different elevations: 1, 2, and 3. Though
they will be in the order of 2, 1, and 3 in our code, the styling will apply an elevation of 1 to
child 1, 2 to child 2, and 3 to child three, making them appear in correct order though they are
not laid out the correct order in our code (listing 4.25).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
106
width: 300,
height: 200,
backgroundColor: '#cccccc',
paddingLeft: 40
},
child: {
width: 150,
height: 150,
position: 'absolute'
},
child1: {
backgroundColor: 'red',
top: 0,
left: 0,
elevation: 1
},
child2: {
backgroundColor: 'orange',
top: 20,
left: 20,
elevation: 2
},
child3: {
backgroundColor: 'blue',
top: 40,
left: 40,
elevation: 3
}
})
As you can see in figure 4.22 or when you run this code, even though child2 comes before
child1 in the code, child1 is behind child2 when the component is rendered.
Next, let’s create a shadow on an iOS element. Before we do so, let’s go over the four
available properties for adding a shadow (usually all used together to get the right effect):
shadowColor
shadowOffset
shadowOpacity
shadowRadius
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
107
SHADOWCOLOR
shadowColor is the color of the shadow (for example, ‘red’, ‘rgba(0,0,0,.3), and so on).
SHADOWOFFSET
shadowOffsetis the distance from the element that the shadow should appear. It takes the
following arguments:
shadowOffset : {
width: number,
height: number
}
SHADOWOPACITY
SHADOWRADIUS
shadowRadius allows us to describe how spread out we would like our shadow to be. The
smaller the number, the less spread out and denser the shadow is. The larger the number, the
more spread out and the less dense it will be.
Let’s set up a basic component and use the above properties to add a shadow (listing
4.26).
container: {
paddingTop: 200,
backgroundColor: '#f4fcff',
paddingLeft: 40,
flex: 1
},
child: {
width: 150,
height: 150,
backgroundColor: 'red',
marginLeft: 90,
shadowColor: 'black',
shadowOffset: {
height: 2,
width: 2
},
shadowOpacity: 0.4,
shadowRadius: 10
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
108
As you can see above, we have set the shadowColor to black, given the shadowOffset a
height of 2 and a width of 2 (which means it will be pushed 2 pixels to the right and down 2
pixels. These can also be negative numbers for the shadow to go up and left), a
shadowOpacity of .4, and a shadowRadius of 10.
TRANSFORMS
Transforms allow you to modify the shape and position of an element in 3d space. What this
means it that we can use this property to do things like rotate, scale, and skew components.
These transform properties are especially useful when working with animations. Transform
takes an array of transform properties, for example:
transform: [{rotate: '90deg ', scale: .5}]
• perspective
• rotate
• rotateX
• rotateY
• rotateZ
• scale
• scaleX
• scaleY
• translateX
• translateY
• skewX
• skewY
We will go over these one by one and see how they work.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
109
PERSPECTIVE
perspective gives an element a 3D-space by affecting the distance between the Z plane and
the user. This is used with other properties to give a 3d effect.
ROTATE
transform: [{ rotate: '45deg' }]
rotate does just what it sounds like it would, it rotates an element. Let’s take our red square
from earlier and rotate it 45 degrees (listing 4.27).
ROTATEX
transform: [{ rotateX: '50deg' }]
rotateX rotates an element on its x axis. It’s not too apparent what is going on if we use our
previous red square, let’s instead use some large text and apply this property (listing 4.28).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
110
Our text should now be rotated 45 degrees on the x axis, skewing the way it looks:
ROTATEY
transform: [{ rotateY: '50deg' }]
rotateY rotates an element on its Y axis. We will use the same example from last time, but
switching the rotateX for rotateY (listing 4.29).
Our text should now be rotated 45 degrees on the y axis, skewing the way it looks:
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
111
ROTATEZ
transform: [{ rotateZ: '50deg' }]
rotateZ rotates an element on its Z axis. We will use the same example from last time, but
switching the rotateY for rotateZ. Let’s also add the backgroundColor back to give us a
better idea of what is going on (listing 4.30).
Our text should now be rotated 45 degrees on the Z axis, rotating it to the right:
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
112
SCALE
transform: [{ scale: .3 }]
scale multiplies the size of the element by the number passed to it, the default being 1. If we
want an element to appear larger, we can pass a value larger than 1, and if we want it to be
smaller, a value smaller than 1. Let’s create three squares, and scale two of them (listing
4.31).
container: {
paddingTop: 100,
backgroundColor: '#f4fcff',
paddingLeft: 40,
flex: 1
},
child: {
width: 50,
height: 50,
marginLeft: 90,
marginTop: 30,
backgroundColor: 'red'
},
scale1: {
transform: [
{scale: .5 }
]
},
scale2: {
transform: [
{scale: 2 }
]
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
113
translate moves an element along the x (translateX) or y (translateY) axis from the
current position. This is not very useful in normal development as we already have margin,
padding, and other position properties available. This is something that becomes very useful
though when we get into animations. To demonstrate this, we will have two components, and
we will add a translateX to one of them (listing 4.32).
child: {
width: 150,
height: 150,
marginLeft: 90,
marginTop: 30,
backgroundColor: 'red'
},
childX: {
transform: [{ translateX: 50 }]
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
114
SKEW
transform: [{ skewY: '50deg' }]
The skew property will skew an element across wither the X or Y axis. Let’s apply these
properties to two square components (listing 4.33).
child: {
width: 150,
height: 150,
marginLeft: 90,
marginTop: 30,
backgroundColor: 'red'
},
childY: {
transform: [{ skewY: '45deg' }]
},
childX: {
transform: [{ skewX: '45deg' }]
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
115
• color
• fontFamily
• fontSize
• fontStyle
• fontWeight
• lineHeight
• textAlign
• textDecorationLine
• textShadowColor
• textShadowOffset
• textShadowRadius
Android only:
• textAlignVertical
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
116
iOS only:
• letterSpacing
• textDecorationColor
• textDecorationStyle
• writingDirection
COLOR
color: 'red'
Let’s create a couple of Text elements and pass them some different colors (figure 4.29 and
the listing).
text1: {
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
117
color: '#06f'
},
text2: {
color: 'rgba(0, 0, 0, .7)'
},
text3: {
color: '#666'
},
text4: {
color: 'red'
}
FONTFAMILY
fontFamily: 'string'
For iOS, there are a large number of available fonts that can be implemented out of the box.
For android, there are only three: (normal(Droid Sans), serif(Droid Serif), and monospace
(Droid Sans Mono)). For a full list of iOS fonts available out of the box in React Native, go to:
https://github.com/dabit3/react-native-fonts.
We can also add custom fonts to our project using font files (ttf, otf, and so on). We will go
over how to add new and custom fonts to our project in a later chapter. For now, let’s just talk
about how to use existing fonts in our project.
Let’s look at how to implement a custom font in iOS using the fontFamily property (listing
4.35).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
118
FONTSIZE
fontSize: 18
fontSize is pretty simple, it just adjusts the size of the text in a Text element. We’ve used
this already quite a bit, so we won’t go into too much detail other than the fact that the
default fontSize is 14.
FONTSTYLE
fontStyle: 'italic'
This is to change the font style to italic. The default is 'normal '. The only two options at this
moment are 'normal ' and 'italic.’
FONTWEIGHT
fontWeight: 'bold'
fontWeight refers to the thickness of the font. The default is 'normal' or '400'.
The options for fontWeightare one of the following: 'normal', 'bold', '100', '200',
'300', '400', '500', '600', '700', '800', '900'. The smaller you go, the lighter /
thinner the text gets. The larger you go, the thicker / bolder the text gets.
LINEHEIGHT
lineHeight: 20
lineHeight specifies the height of the text element. When using lineHeight, the default
functionality is that the text will be aligned at the bottom.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
119
Let’s take a look at an example and then view it in our inspector to see this in action. We
will set up three Text elements, and give the middle element a lineHeight of 50 (listing
4.37).
As you can see above (iOS simulator and debugger) highlighted in the darker blue, the height
of the middle text element is larger than the others. Also notice that all of the height has been
added to the top of the element.
This is only true in iOS. In Android, the opposite is true. The text will be aligned to the top
in Android, not the bottom.
TEXTALIGN
textAlign: 'center'
textAlign refers to how the text in the element will be horizontally aligned.
The options for textAlign are the following:
'auto', 'center', 'right', 'left', 'justify' ('justify' is iOS only).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
120
Setting the textAlign property will change the horizontal alignment of the text in the
element.
TEXTDECORATIONLINE
textDecorationLine: 'underline '
TEXTSHADOW
textShadow encompasses the following three properties:
textShadowColor: 'red '
textShadowOffset: {width: -2, height: -2}
textShadowRadius: 4
This property allows us to add a shadow to a Text element. Let’s incorporate this into a
component to see how it works (listing 4.38).
As you can see, the text shadow is starting from the left and the top of the text. This is
because we declared width and height of -2.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
121
The options for textAlignVertical are 'auto', 'top', 'bottom', and 'center'.
This will allow us to choose the alignment position of our text The default value for this
property in Android is ' top '. This is especially useful when using the lineHeight property
(listing 4.39).
LETTERSPACING(IOS ONLY)
letterSpacing: 2
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
122
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
123
WRITINGDIRECTION
writingDirection: 'rtl'
writingDirectiongives us control over the direction that the text is displayed (right to left,
left to right). This is especially useful when implementing internationalization.
writingDirection can take any of the following properties: 'auto', 'ltr', 'rtl'
4.3 Summary
In this chapter, we learned:
• Styling can be applied inline or by using a StyleSheet and referencing the style variable
used when creating the StyleSheet.
• Styling View components
• Styling Text Components
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
124
5
Styling in depth
• Flexbox
• Dynamic Styles
• Organizing styles
• Summary
Now that we have an understanding of styling elements in React Native, as well as how to use
them, we’ll take a look at the React Native layout system using Flexbox. FlexBox is a
fundamental concept that needs to be properly understood to create layouts and UIs in React
Native.
We’ll put all of the styling knowledge we have together and harness props and state to
dynamically style our components, styling and updating styles based on these properties.
Next, we’ll talk about a few ways to define styles that we will be reusing by exporting and
importing them into other files and components.
Finally, we’ll talk about a few different strategies and best practices that make for practical
code organization.
5.1 Flexbox
Flexbox is a layout implementation that React Native uses to provide an efficient way for users
to create UIs and control positioning in React Native. The React Native Flexbox
implementation is based on the W3C Flexbox web specification, but does not share 100% of
the APIthat the W3C implementation carries with it. It aims to give us an easy way to reason
about, align and distribute space among items in our layout, even when their size is not
known or even when their size is dynamic. Flexbox layout is only available for use on View
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
125
components. To better understand how Flexbox works, let’s go ahead and take a look at some
code.
Listing 5.1 flex property Using the flex property in your styling
flex: 1
The flex number specifies the ability of the item to alter its dimensions to fill the space of the
container that it is within. This value is relative to the rest of the items within the same
container.
This means that if we have a View element with a height of 300 and a width of 300, and a
child View with a property of flex: 1, then the child view will completely fill the parent view.
If we decide to add another child element with a flex property of flex: 1, they will each take up
equal space within the parent container.
Another way to look at this is to think of the flex properties as being percentages. For
example, if you would like your child components to take up 66.6% and 33.3% respectively,
you could use flex:66 and flex:33, which would also work, with the first item occupying 2/3
and the second item occupying 1/3 of the parent container. The flex number is only important
relative to the other flex items occupying the same space. Thinking about flex numbers in
percentages sometimes makes it much easier to reason about.
To better understand how this all works, let’s take a look at a couple of diagrams depicting
Views with a few different flex values:
container: {
width: 300,
height: 300,
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
126
marginTop: 150,
backgroundColor: 'white'
},
flex1: {
flex: 1,
backgroundColor: '#666666'
}
As you can see, this filled the entire 150 width and height with the child box. Next, let’s add
another box next to it with a lighter shade of gray:
Listing 5.3 flex property Example with two flex items in code
<View style={styles.container}>
<View style={styles.flexBox1} />
<View style={styles.flexBox2} />
</View>
container: {
width: 300,
height: 300,
marginTop: 150,
backgroundColor: 'white'
},
flexBox1: {
flex: 1,
backgroundColor: '#666666'
},
flexBox2: {
flex: 1,
backgroundColor: '#ededed
}
Now, we see that there is still a single square container but our two boxes now share equally
the space of the parent container. Next, let’s change the flex property of the second box to
flex:2 and see what happens:
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
127
Listing 5.4 flex property Example of two flex items with different flex properties in code
<View style={styles.container}>
<View style={styles.flexBox1} />
<View style={styles.flexBox2} />
</View>
container: {
...
},
flexBox1: {
flex: 1,
backgroundColor: '#666666'
},
flexBox2: {
flex: 2,
backgroundColor: '#ededed
}
Now, the second flex item takes up twice as much space as the first flex item.
There are two options for this property: row and column. The default setting is column. If you
do not specify a flexDirection property, your content will lay out in a column layout as we saw
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
128
before because column is the default layout. Let’s change this to flexDirection: row and see
how it looks. Everything else in our code will stay the same:
container: {
width: 150,
height: 150,
marginTop: 150,
backgroundColor: 'white',
marginLeft: 20,
flexDirection: 'row'
},
flexBox1: {
...
},
flexBox2: {
...
}
As you can see, the child elements now lay out left to right. This property is something that
you will use a lot when developing apps in React Native so it is important to grasp it and
understand how it works.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
129
There are four options for this property: flex-start, flex-end, center, and stretch. The default
value is stretch, so if no other value is declared, stretch is the behaviour you will get out of the
box.
Let’s create a component to test out this property:
As you can see, the flexBox1 style and child take up the entire width of the container.
Everything that happens concerning alignItems is relative to the flexDirection. As you can see,
we have not declared a flexDirection, so we are getting the flexDirection column behaviour as
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
130
it is the default. Let’s add flexDirection:'row' to the parent container and see what happens.
Keep in mind that the behaviour we are seeing is the same as if we declared alignItems:
'stretch' on the parent container:
Listing 5.9 Adding flexDirection to the container Adding flexDirection to container in code
container: {
...
flexDirection: 'row'
}
Let’s change only alignItems property of the container by adding alignItems: 'center' to the
styling. We’ll be keeping the flexDirection: 'row' property for now:
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
131
Now, the content is centered vertically. Next, let’s remove the flexDirection: 'row'property:
Because the flexDirection is now defaulted to column, the content is centered horizontally.
Changing between the row and column flexDirection and understanding alignItems along
with the soon to be covered justifyContent can sometimes get confusing as they change based
on flexDirection. Don’t worry about understanding this exactly right away. Just remember that
being aware of how these properties affect each other should allow you to debug and
troubleshoot much easier.
Next, let’s implement the same view with alignItems: 'flex-start'. flex-start will align the
items with the beginning of the parent container:
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
132
Because both alignItems properties begin their axes at the top left of the container, they both
will render as shown above.
Finally, let’s implement alignItems: 'flex-end', with no flexDirection property:
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
133
The items now vertically align flush with the end of the container. This is because our
flexDirection is defaulted to column.
Now, we will change the flexDirection property to 'row':
Listing 5.13 alignItems: 'flex-end' with flexDirection: 'row' alignItems: 'flex-end' with
flexDirection: 'row' in code
container: {
...
alignItems: 'flex-end',
flexDirection: 'row'
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
134
Now that our flexDirection has changed to row, the end of the flex container is rendered as
being the bottom vertically. Remember that the columns stack vertically, and the rows stack
horizontally. This means the the beginning and end of the column will be left and right, while
the beginning and end of the row will be top and bottom.
There are five options for this property: flex-start, flex-end, center, space-around, and space-
between. The default value is flex-start, so if no other value is declared, flex-start is the
behaviour you will get out of the box.
Let’s take another look at the component we have been working with so far:
container: {
width: 150,
height: 150,
marginTop: 150,
backgroundColor: '#ededed',
marginLeft: 20
},
flexBox1: {
backgroundColor: '#666666'
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
135
As you can see, our content displays at the top of the parent container. This is the behavior
we will get if we applied justifyContent: 'flex-start' as well. Now, let’s append the
justifyContent: 'flex-end' property to our container style:
Now we see the content move to the end of the container. If we were using flexDirection:
'row' as our layout, the content would instead move to the right side of the container, taking
up the entire height.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
136
Next, let’s implement justifyContent: 'center'. This will center our content in the parent
container:
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
137
<Box />
<Box />
</View>
)
}
}
The last property we will implement will be the space-around property. space-around will
basically distribute items evenly with all items having equal space around them.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
138
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
139
Now we have independent control of the alignment of the child items. If there is an alignItems
property on the parent container, alignSelf will override the alignItems property.\
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
140
Listing 5.21 flexWrap property flexWrap not defined (defaults to no-wrap) in code
class App extends Component {
render () {
return (
<View style={styles.container}>
<Box />
<Box />
<Box />
<Box />
<Box />
</View>
)
}
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
141
We have declared five boxes in our layout, but as you can see only two of them are shown
with the third overflowing off of the screen. Now, let’s add the flexWrap: 'wrap' property to the
container:
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
142
With flexWrap: 'wrap' declared, we see that any items that would be rendered off of the
screen instead now wrap nicely into our view.
Listing 5.23 Dynamic styling with props Dynamic styling with boolean prop value in code
class App extends Component {
render () {
return (
<View style={styles.container}>
<Box border />
<Box />
</View>
)
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
143
What we’ve done is passed down a boolean value of border to the Box component. We check
to see if the border prop is passed, if it is then we apply the border style. Any type of logic can
be used here, and we will look at a few other ways of going about doing this. How you use
dynamic styles in your components will entirely depend on circumstance and what your
component is trying to do.
Another common styling use case is passing down color properties as props. Let’s take a
glance at how that would work:
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
144
We pass down a backgroundColor of yellow to the Box component. If it is defined, we set the
backgroundColor to the backgroundColor that was passed using an es6 shorthand property
name.
Working with dynamic styles based on state values is very similar in concept to working
with dynamic styles based on prop value. Let’s take a look at an example of how this would
work:
Listing 5.25 Dynamic styling based on state Dynamic styling with state value
class App extends Component {
constructor () {
super()
this.state = {loaded: false}
}
componentDidMount () {
setTimeout(() => {
this.setState({
loaded: true
})
}, 1000)
}
render () {
const { loaded } = this.state
return (
<View style={styles.container}>
<Box backgroundColor={loaded && 'yellow'} />
</View>
)
}
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
145
Listing 5.26 Dynamic with helper function Dynamic styling with helper function
const colors = ['red', 'blue', 'yellow', 'green']
function getRandomNum () {
const index = Math.floor(Math.random() * (4))
console.log('index:', index)
return colors[index]
}
class App extends Component {
render () {
return (
<View style={styles.container}>
<Box backgroundColor={getRandomNum()} />
<Box backgroundColor={getRandomNum()} />
<Box backgroundColor={getRandomNum()} />
<Box backgroundColor={getRandomNum()} />
</View>
)
}
}
Here we are calling getRandomNum() from within our component and returning a random
color from our array.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
146
Listing 5.27 Dynamic with helper function Dynamic styling of rows based in index
let people = ['Jennifer', 'Chris', 'Emily', 'Becky', 'Mark']
Figure 5.21
Here we are simply mapping through all of the items in our people array, and setting the
backgroundColor to yellow based on whether the index is even or odd.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
147
Then, we can import and reuse these styles whenever necessary as we would if they were
declared within our component:
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
148
Another technique to keep in mind is that we can also create multiple stylesheets within the
same file. This may come in handy if we are also wanting to create a separate group of ui
elements that we may want to have access to without having to import the entire stylesheet:
<View style={styles.container}>
<TouchableHighlight style={buttons.primary} />
...
</TouchableHighlight>
</View>
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
149
6
Cross-platform components
• An overview of what components are and which ones ship with React Native
• How to implement the native components that ship with React Native
• What the ListView component is and how to implement it in your application
• Understanding touch events and the components that allow touch events
• Summary of the cross platform components and their implementations
There are many components that ship with React Native that ship with React Native and are
ready to be used for your app. Some of these components work cross platform; that is, they
will work regardless of whether you are running your app on iOS or Android. Some are
platform specific.
In this chapter, I cover all the cross platform components and how to implement each one.
I walk through their APIs and talk about use cases that may be ideal for each one.
An example of the types of components we will be covering are things like View and Text
elements, which are cross platform, and we have discussed them already in the previous
chapters. An example of a non-cross-platform component is ToolbarAndroid, which only runs
on Android, or ActionSheetIOS, which would only be for iOS.
When building your application, these components will be the building blocks for your app.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
150
6.1.1 ActivityIndicator
ActivityIndicator is a native component that displays a loading indicator to indicate loading. An
ideal use case for this would be to show it while data is loading, or something is processing in
your app to let your user be aware of this.
ActivityIndicator takes the following properties, all optional, as shown in table6.1.
Let’s set up an activity indicator to simulate page loading that depends on data from an
external api call, which is a common use case. We will create a new React Native component
with an initial state variable called loading set to true. We will call a setTimeOut function
when the component loads which will set the loading variable to false after four seconds,
which will hide the ActivityIndicator when the timeout triggers (listing 6.1).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
151
alignItems: 'center',
flex: 1
}
})
In figure 6.1, the screen on the left shows the ActivityIndicator when the page loads, and after
the state of loading is set to false, the message “Component Now Loaded” is then rendered to
the screen.
This code is also located at:
https://github.com/dabit3/react-native-in-action/tree/chapter6/Listing_1-1
6.1.2 Image
Image is a native component used for displaying different types of images, including network
images, static resources, temporary local images, and images from local disk, such as the
camera roll.
Image takes the following properties (table6.2).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
152
When specifying an image source, you can either do so locally or remotely with a uri using the
following syntax (listing 6.2).
We will now implement Image components using some of these methods and properties to see
how they work.
The first group of properties we will look at are resizeMode, source, and style. You will
probably be using the source and style properties every time you implement an Image
component using React Native.
Let’s go over how each resizeMode property works so we can understand how to use them
in the future.
• contain – will scale the image uniformly, maintain the image's aspect ratio, so that
both dimensions (width and height) of the image will be equal to or less than the
corresponding dimension of the view (minus padding). This will keep the image within
the boundaries of the component.
• cover – will scale the image uniformly, maintaining the image's aspect ratio, so that
both the width and height of the image will be equal to or larger than the
corresponding dimension of the view (minus padding). This will scale the image up to
fill the entire component.
• stretch – will scale width and height independently. This may change the aspect ratio
of the source. If an image is not large enough to fill the component, this will cause the
image to stretch to fit, usually changing the aspect ratio.
• repeat (iOS only)–will repeat the image to cover the frame of the component. The
image will keep it's size and aspect ratio.
• center–will center the image in the component
We will render the same image five times, using all of the available resizeMode properties
(listing 6.4).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
153
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
154
Images can also take other components as children. One reason to do this would be to use an
Image component to hold a background image. Let’s implement this and see how it would look
(listing 6.5).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
155
return (
<View style={styles.container}>
<Image
style={styles.image}
source={{uri}}>
<Text style={styles.text}>Hello From Image!</Text>
</Image>
</View>
)
}
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
156
Next, we will implement an image along with some of the methods that will tell us when the
image starts to load and when it finishes loading. We will call onLayout to measure the x and
y position of the image as well as the width and height and then display these values in our
view. We will call onLoadStart when the image begins and show a message ‘Starting to load’,
and then call onLoad once the image has successfully loaded to show ‘Finished loading’ (listing
6.6).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
157
height: undefined ❷
}
}
onLayout (event) {
const { y, width, x, height } = event.nativeEvent.layout
this.setState({y, width, x, height}) ❻
}
onLoadStart () {
this.setState({startedLoading: true}) ❹
}
onLoad () {
this.setState({finishedLoading: true}) ❺
}
render () {
const uri = 'https://facebook.github.io/react/img/logo_og.png'
return (
<View style={styles.container}>
<Image
onLayout={this.onLayout.bind(this)} ❸
onLoadStart={this.onLoadStart.bind(this)} ❸
onLoad={this.onLoad.bind(this)} ❸
style={styles.image}
source={{uri}} />
{this.state.startedLoading &&<Text>Starting to load</Text>} ❼
{this.state.finishedLoading &&<Text>Finished loading</Text>} ❽
<Text>X: {this.state.x}</Text>
<Text>Y: {this.state.y}</Text>
<Text>Width: {this.state.width}</Text>
<Text>Height: {this.state.height}</Text>
</View>
)
}
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
158
❹ When onLoadStartis called, which happens when the image begins to load,we set the state of
startedLoading to true
❺ When onLoad is called, which happens when the image is finished loading, we set the state of
finishedLoading to true
❻ When the image is loaded, onLayout is called, letting us get the x & y values as well as the width and height of
the component, which we then set in our state, and display in our view
❼ Only show the “Starting to load” message when this.state.startedLoading is true
❽ Only show the “Finished loading” message when this.state.finishedLoading is true
6.1.3 Modal
React Native has a built in modal that can be used to present content above an enclosing
view.Modal can take the following properties (table 6.3).
animationType string (none, slide, or fade) controls how the modal animates in and out
(default is none)
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
159
visible boolean this property controls whether the modal is visible or not
visible
onRequestClose function a function that will be called once the modal has been
dismissed. This method is optional on iOS and required on
Android
onShow function - a function that will be called once the modal has been
shown.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
160
)
}
}
6.1.4 Picker
React Native has a built in Picker component that can be used to render the native picker
component on iOS and Android.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
161
Android only
enabled boolean (default is true) if set to false, the picker will be disabled, i.e. the user
will not be able to make a selection
mode string (dialog or dropdown) specifies how to display the selection items when the
(default is dialog) user taps on the picker
iOS only
itemStyle object (style) will apply styling to each Picker item label
onValueChange function (value, itemPosition) this is a callback function that is fired when the picker
value is changed. it takes the value and index as
parameters.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
162
To render the Picker, we return an instance of the Picker element, and give it a
selectedValue value, an onValueChange method, and a list of child elements to render. Each
of these child elements is rendered as a Picker.Item, and needs a label and value property
(listing 6.8).
For our real world example, we will render out a list of restaurant types, and let the picker
render to the view the restaurant type and whether or not the restaurant is romantic (listing
6.9).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
163
restaurants.map((l, i) => { ❹
return <Picker.Item key={i} label={l.type} value={l.type} />
})
}
</Picker>
<Text
style={{textAlign: 'center'}}>
{this.state.restaurant.type} ❻
</Text>
{this.state.restaurant.romantic&& ❼
<Text
style={{textAlign: 'center', marginTop: 10}}>ROMANTIC!
</Text>}
</View>
)
}
}
❶ Set the initial state with an object named restaurant. The restaurant has a type value set to Italian, and
romantic value set to true.
❷ Create an array of restaurants, each with a type and romantic value set.
❸ Set the initial selectedValue property to this.state.restaurant.type.
❹ Map over the restaurants and return a Picker.Item for each restaurant. Set the key property to the index,
the label property to the type, and the value property to the type.
❺ Set the onValueChange method to take in the value (value property set on the Picker.Item) and the position
(index) as arguments. When a position is chosen, the state is reset and restaurant is set to the item in the array at
the chosen index.
❻ this.state.restaurant.type is rendered using a Text element.
❼ If the romantic key of the chosen restaurant is true, we show that it is romantic.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
164
Figure 6.7 Restaurant picker from listing 6.x rendered on iOS and Android
6.1.5 ScrollView
ScrollView is a component that wraps other components and allows native scrolling behaviour,
both horizontally and vertically.
ScrollView can take the following properties (table6.5).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
165
keyboardDismissMode string (none, interactive, or determines whether the keyboard gets dismissed
on-drag), (default is none) in response to a drag. - 'none' (the default), drags
do not dismiss the keyboard. - 'on-drag', the
keyboard is dismissed when a drag begins. -
'interactive', the keyboard is dismissed
interactively with the drag and moves in
synchrony with the touch; dragging upwards
cancels the dismissal. On android this is not
supported and it will have the same behavior as
'none'.
keyboardShouldPersistTaps boolean (default is false) when false, tapping outside of the focused text
input when the keyboard is up dismisses the
keyboard. When true, the keyboard will not
dismiss automatically, and the scroll view will not
catch taps, but children of the scroll view can
catch taps.
onScroll function fires at most once per frame during scrolling. The
frequency of the events can be controlled using
the scrollEventThrottle prop.
pagingEnabled boolean (default is false) when true, the scroll view stops on multiples of
the scroll view's size when scrolling. This can be
used for horizontal pagination.
removeClippedSubviews boolean (default is true) experimental: When true, offscreen child views
(whose overflow value is hidden) are removed
from their native backing superview when
offscreen. This can improve scrolling
performance on long lists.
showsHorizontalScrollIndicator boolean (default is true) When true, shows a horizontal scroll indicator.
showsVerticalScrollIndicator boolean (default is true) When true, shows a vertical scroll indicator.
In our example, we will render a View with two ScrollViews as children. One will scroll
vertically and the other will scroll horizonally (listing 6.10).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
166
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
167
6.1.6 RefreshControl
The RefreshControl component is used inside of a ScrollView or ListView component to add
pull to refresh functionality.
RefreshControl can take the following properties (table6.6).
Android only
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
168
indicator
iOS only
In our example, we will render a ScrollView and mock an API by setting a setTimeout
whenever the onRefresh event is fired (listing 6.11). When the ScrollView is pulled down, the
RefreshControl will show while the state is being updated.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
169
render () {
const { numRows, refreshing } = this.state
const rows = []
for (var i = 0; i < numRows; i++) {
rows.push(<Text key={i} style={styles.row}>
Welcome to React Native + {i}!
</Text>)
}
return (
<View style={{flex: 1, marginTop: 30}}>
<ScrollView
refreshControl={ ❹
<RefreshControl
refreshing={refreshing}
onRefresh={this.refreshRows.bind(this)}
/>
}
showsVerticalScrollIndicator={false} >
{rows}
</ScrollView>
</View>
)
}
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
170
6.1.7 Slider
Sliders are used to select single values from a range. For instance, if you have a form you
would like to be populated with a certain numeric value, you could use a slider to make it
easier for the user to populate the form with the correct value.
A Slider can take the following properties (table6.7).
Table6.7 Slider
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
171
onSlidingComplete function callback function called when the user finishes changing
the value (when the slider is released).
onValueChange function funciton continuously called while the user is dragging the
slider.
step Number (default is 0) step value of the slider. the value should be between 0
and (maximumValue - minimumValue).
value number (default is 0) nitial value of the slider. The value should be between
minimumValue and maximumValue, which default to 0
and 1.
iOS Only
maximumTrackImage, image source assigns the min and max track images. only static images
minimumTrackImage are supported. the leftmost pixel of the image will be
stretched to fill the track.
maximumTrackTintColor, color the color used for the track to the right and left of the
minimumTrackTintColor button. overrides the default blue gradient image.
thumbImage image source sets an image for the thumb. only static images are
supported. assigns a single image for the track. Only static
images are supported. the center pixel of the image will
be stretched to fill the track
trackImage image source assigns a single image for the track. only static images
are supported. the center pixel of the image will be
stretched to fill the track.
In our example, we will create a slider that will let the user choose a value between 1 and
100, with the step being 1 (listing 6.12).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
172
}
render () {
const { number } = this.state
return (
<View style={{flex: 1, margin: 20, marginTop: 30}}>
<Slider ❸
step={1}
minimumValue={0}
maximumValue={100}
onValueChange={(value) => this.setState({number: value})}
/>
<View>
<Text>{number}</Text> ❹
</View>
</View>
)
}
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
173
6.1.8 Switch
The Switch component is a way for users to toggle or choose boolean values from the UI.
The Switch component takes the following properties (table6.8).
iOS only
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
174
In our example, we will create a switch that toggles a View component in and out of view
(listing 6.13).
6.1.9 TextInput
The TextInput component allows users to input text in your app. It is a very important
component to get to know as you will be using it quite a bit when building React Native apps.
The TextInput component has a very large number of properties so we will not be covering
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
175
them all. Instead, I will focus on the most important ones and the ones I have noticed I’ve
needed in my own development (table6.9).
autoCapitalize boolean (default is false) will autocapitalize certain characters in the input field
autoCorrect boolean (default is true) will provide autoCorrect functionality in the input field
autoFocus boolean (default is false) will automatically focus the TextInput when
componentDidMount is called
blurOnSbmit boolean (default is true for will blur, or unfocus, the input field when the form is
single line inputs, false for submitted
multiline inputs)
onSubmitEditing function (only for single line called when the submit button is pressed
TextInput)
returnKeyType string (done, go, next, search, or specify the type of return key
send. Default is return for iOS,
checkmark icon for Android)
secureTextEntry boolean (default is false) hides the value of the input in the UI, ideal for
passwords.
In our example, we will have a TextInput that renders the value of the input to the UI in a
Text component (listing 6.15).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
176
let styles = {}
In this example, we are also using the Platform component from React Native, which allows us to detect which
platform we are currently on and apply specific styling based on the Platform.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
177
6.1.10 TouchableWithoutFeedback
TouchableWithoutFeedback is one of a few ways to make Views responsive to touch events
(the others being TouchableOpacity, TouchableNativeFeedback (Android only, will go over in a
later chapter), and TouchableHighlight.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
178
accessible boolean (default is true) allows the component to be accessible to screen reader
delayPressIn function delay in ms, from the start of the touch, before onPressIn is
called
onLongPress function called when the element is pressed and held down, used with
delayLongPress
hitSlop object {top: number, left: this defines how far your touch can start away from the
number, bottom: button. This is added to pressRetentionOffset when moving off
number, right: number} of the button.
onPress function called when the touch is released, but not if cancelled (e.g. by
a scroll that steals the responder lock).
pressRetentionOffset object {top: number, left: When the scroll view is disabled, this defines how far your
number, bottom: touch may move off of the button, before deactivating the
number, right: number} button.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
179
View,
TouchableWithoutFeedback, ❶
StyleSheet
} from 'react-native'
let styles = {}
styles = StyleSheet.create({
button: {
height: 50,
backgroundColor: '#dddddd',
justifyContent: 'center',
alignItems: 'center'
},
buttonText: {
color: 'white'
}
})
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
180
❺ if the showName value is true, the Text component will render, if it is false, it will not render
6.1.11 TouchableHighlight
TouchableHighlight takes the same props as TouchableWithoutFeedback along with a few
more. The main difference between TouchableWithoutFeedback and TouchableHighlight is that
the TouchableHighlight has an underlay color (underlayColor prop) that show when the button
is pressed, giving the user feedback that the press event happened (table6.11).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
181
onHideUnderlay function function that is called immediately after the underlay is hidden
In our example, we will render a basic TouchableHighlight component with an onPress method
attached to a console.log statement (listing 6.17).
styles = StyleSheet.create({
button: {
backgroundColor: '#666',
height: 50,
justifyContent: 'center',
alignItems: 'center',
margin: 20,
marginTop: 100
},
buttonText: {
color: 'white'
}
})
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
182
6.1.12 TouchableOpacity
TouchableHighlight takes the same props as TouchableWithoutFeedback along with another
single property, activeOpacity (opacity, number). The main difference between
TouchableHighlight and TouchableOpacity is that TouchableOpacity has less configuration and
is an easy way to create a simple button component without a lot of work.
6.2 Summary
• Overview of most cross platform React Native components
• Overview and implementation of props and methods of cross platform components
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
183
7
Navigation
Navigation in React Native is a very important concept to understand when building your
application.
There are many options out there for creating and managing navigation state for a React
Native application, but only three come out of the box, so we will be covering those. They are
NavigatorIOS, Navigator, and Navigation Experimental.
Navigation state is usually held in an array and routes are pushed and popped to the array,
rendering the current chosen item in the array. We navigate through our routes by pushing
and popping to the array, rendering the chosen route (listing 7.1).
// push to route
routes.push({
component: Contact,
title: 'Contact'
})
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
184
This is a very basic implementation of how a route array works, and what it looks like to push
and pop routes to the route array. This concept will be applicable to all the navigation options
we look at in this chapter, and also carry on to most navigation options in general when
dealing with React Native.
7.1 NavigatorIOS
The first navigation option we will be covering in this chapter is NavigatorIOS. This navigator
is great for beginners, prototypes, or applications that do not require a complex navigation
state, and applications that only need to run on the iOS platform. To be clear, this navigator
will not work on Android.
The main benefits of NavigatorIOS are its simple API and smooth transitions. While many
of the other options available for navigation use JavaScript for animating the transitions
between routes, NavigatorIOS uses real native transitions, giving it a slightly smoother feel
and truly native performance. It is also very easy to get up and running.
In the context of NavigatorIOS, a route is an object with at least one property: a
component.
{component: MyComponent}
For our basic example, we will set up a navigator that pushes and pops a couple of routes. We
will specify a ref, tintColor, titleTextColor, and initialRoute on the original instance of
the NavigatorIOS, and have three components that we will navigate between (Home, About,
and Contact).
To set up an instance of NavigatorIOS, there are really only two things that must be given
as props: a style of flex:1, to fill the view with the navigator, and an initialRoute object
with a title and component property.
class App extends Component {
render () {
return (
<NavigatorIOS
style={{ flex: 1 }}
initialRoute={{ title: 'Home', component: Home }}
/>
)
}
}
With that in mind, let’s code our first application using NavigatorIOS. Our application will
consist of three routes: Home, About, and Contact. The initial route will be a component we
will call Home (listing 7.2, figure 7.1).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
185
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
186
<View style={styles.container}>
<Text style={styles.text}>About</Text>
<Text
style={styles.text}
onPress={() => navigator.pop()} ❹
>Go Back</Text>
<Text
style={styles.text}
onPress={() => navigator.replace({
component: Contact,
onLeftButtonPress: () => navigator.pop() ❺
})
}
>Go to Contact</Text>
</View>
)
styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 60,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'orange'
},
text: {
fontSize: 20,
padding: 7
}
})
AppRegistry.registerComponent('App', () => App)
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
187
❷ create a component called Home. Notice that we get access to navigator as props, this is because any component
that gets rendered by NavigatorIOS anywhere in the routes stack automatically gets passed the navigator reference
as a prop.
❸ create an onPress method that calls navigator.push, passing in a title, component, leftButtTitle,
and onLeftButtonPress method. If we do not pass in a leftButtonTitle or onLeftButtonPress
method, the default that is rendered is a Back button that will call navigator.pop() when pressed.
❹ in About, we have a back button that calls navigator.pop() to go back
❺ in About, we also have a button that calls navigator.replace, replacing the current route with the Contact
component. Using replace will not render any animations at all, instead it will just replace the current scene without
any transitions or animations.
❻ in the render method, we return the instance of NavigatorIOS, passing in all of the configuration we will need to
wire everything together. Notice we also have a ref= 'navigator' which gives us access to the navigator
methods within the initial component. We do this so we can give the initailRoute object access to the
navigator push method in the onRightButtonPress function by calling this.refs.navigator.push.
NavigatorIOS has the props and methods shown in tables 7.1 and 7.2.
tintColor string text and icon color for buttons in the navigation
bar
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
188
replace replace({route}) replaces the route for the current scene and
immediately load the view for the new route.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
189
Listing 7.3 Basic Navigator implementation (not full implementation, will not run)
import Home from './pathtohomecomponent/'
<Navigator
initialRoute={{ name: 'Home', component: Home }}
renderScene={(route, navigator) =><route.component />}
/>
One thing to remember is that any route properties, such as the name or the component values
in listing 7.3, will be available as properties of the route argument of renderScene. That is
why we can use <route.component /> to render our scene, as we are returning the Home
component as the initialRoute component value. TheinitialRoute object has both a
component and name key, which we then access in renderScene as route.component.
Navigator also has a way to specify scene animations and custom header that calls
methods, all of which we will cover shortly, but first let’s set up an instance of Navigator so we
can begin working with it.
To get started, we will need to create a component for our initial route and a component
that will render the navigator (Listing 7.4, figure 7.2).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
190
styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 60,
justifyContent: 'center',
alignItems: 'center'
},
text: {
fontSize: 20,
padding: 7
}
})
Now, when we run our app, we should get the Home component rendered when the app starts
(figure 7.2).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
191
Now that we have our Navigator working, let’s add a couple of routes that we can navigate
between. In the same file, below the Home declaration, let’s create two more components,
Contact and About. We will also update the Home component to take the navigator props and
link to the two new components (Listing 7.5).
❶ Home is updated to take the navigator prop that was passed as a prop in the renderScene method, and use it to
call navigator.push to navigate to the <About /> and <Contact /> components we created. We push to a new route
by calling navigator.push, passing an object with both component and title values specified (title will be used
shortly when we create a navigation header).
❷ About and Contact also take the navigator prop that was passed in renderScene and return a basic component
with a back button that calls navigator.pop().
Now we should be able to click on About and Contact from the Home screen to navigate to our
new components.
With our new components working, let’s now add a navigation bar. To enable a
navigationBar, we need to destructure the NavigationBarfrom the Navigator, create a
NavigationBar component and pass it as a prop to the navigationBar in Navigator.
Destructuring NavigationBarfrom Navigator is the same as calling Navigator.NavigationBar
but in a more concise manner (Listing 7.6, figure 7.3).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
192
const NavBar = ( ❷
<NavigationBa r ❸
style={{ borderBottomWidth: 1, borderBottomColor: '#ededed' }}
routeMapper={{ ❹
LeftButton: (route, navigator, index, navState) => {
if (index === 0) return null
return (<Text style={styles.backButton} onPress={navigator.pop}>Back</Text>)
},
RightButton: (route, navigator, index, navState) => {
return null
},
Title: (route, navigator, index, navState) => {
return (<Text style={styles.title}>{route.title}</Text>)
},
}}
/>
)
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
193
The Title component will return the route title, the LeftButton will call navigator.pop,
The LeftButton component will check to see if we are on the initial route (index === 0). If we are on the initial
route, it will return null. If we are not on the initial route, it will return a back button that calls navigator.pop
Now that we have created a NavBar component, the last thing we need to do is pass it in as a
prop to the Navigator. In the render method, when we return the Navigator, pass the NavBar
in as a navigationBar prop. (listing 7.7).
Now when we run our app we should get a navigation bar (figure 7.3).
With the current setup, we see that when we navigate to a new page the transitions
happen from right to left, and when we go back the go from left to right. What if we want to
specify a certain type of transition? Doing so with this component is very straightforward.
Navigator also has a prop called configureScene which lets us specify how we want the scene
to animate (Listing 7.8).
The default configuration is PushFromRight, so nothing different will happen when we specify
PushFromRight, but there are quite a few options to choose from (listing 7.9).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
194
configureScene is invoked with two parameters, the route and the routeStack.
(route, routeStack) =>SceneConfigs.FloatFromBottom
One way to dynamically implement one of these scene configurations is to create a method
that can be attached to the configureScene prop and do logic on the route. That is, in the
route object we can pass parameters to check for in the configureScene method.
In our example, we will check to see if there is a type: 'modal' in the route, and if so we
will float the scene from the bottom like a Modal window.
After the renderScene method, we will create a configureScene method. We will also
create a new component called Modal and update the Home component to have a new link
called Modal. (listing 7.10).
❷
const Modal = ({ navigator }) => (
<View style={[styles.container, { backgroundColor: 'red' } ]}>
<Text style={styles.text}>Modal</Text>
</View>
)
...
❸
constructor() {
super()
this.renderScene = this.renderScene.bind(this)
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
195
this.configureScene = this.configureScene.bind(this)
}
...
❹
configureScene (route) {
const { SceneConfigs } = Navigator
if (route.type === 'modal') {
return SceneConfigs.FloatFromBottom
} else {
return SceneConfigs.FloatFromRight
}
}
...
❺
render () {
return (
<Navigator
navigationBar={NavBar}
configureScene={this.configureScene}
ref='navigator'
renderScene={this.renderScene}
initialRoute={{ title: 'Home', component: Home }}
/>
)
}
❶ Add a new route called Home, and add a new type property to the route object.
❷ Create a new component called Modal, and give it a background color of red so we can see the exact transition and
how it differs from the others.
❸ In the existing constructor, we bind the new configureScene method to the class.
❹ In the newly addedconfigureScene method, we check to see if the route.type is modal. If it is, we float
the scene from the bottom. If it is not, we float it in from the right.
❺ In the existing Navigator, we add a new prop called configureScene and pass in our new configureScene
method.
Now when we press Modal, we see the nice bottom to top transition, while all our other
transitions stay the same!
What if we need to pass properties to another scene? With Navigator, we can do this pretty
easily.
The first thing we need to do is go back to our renderScene method and tell it to pass
along any properties to each component being returned (Listing 7.11).
To pass props, we can now just add a props key to the route object (listing 7.12).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
196
Now, the author prop will be available in the Modal component (listing 7.13).
Navigator also has the props and methods shown in tables 7.3 and 7.4.
onDidFocus function Required function which renders the scene for a given
route. Will be invoked with the route and the navigator
object.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
197
jumpForward() none Jump forward to the next scene in the route stack.
push(route) route (object) Navigate forward to a new scene, squashing any scenes
that you could jump forward to.
replace(route) route (object) Replace the current scene with a new route.
popToTop() none Pop to the first scene in the stack, unmounting every
other scene.
popToRoute(route) route (object) Pop to a particular scene, as specified by its route. All
scenes after it will be unmounted.
replacePreviousAndPop(route) route (object) Replace the previous scene and pop to it.
resetTo(route) route (object) Navigate to a new scene and reset route stack.
A new Navigation system for react native. Focuses on the following improvements over <Navigator />:
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
198
Navigation logic and routing must be independent from view logic to allow for a variety of native and js-based
navigation views
What does this mean for us? Well, at this point we have yet to run into any pitfalls with either
Navigator or NavigatorIOS, but in many larger applications, navigation state can become
complex and hard to reason about. While using Navigator, we also have to keep up with our
navigator instance, which can be tiresome, as it would have to be passed down as a prop to
child components wherever we need it.
NavigationExperimental offers a central location that we can keep up with and update our
navigation, and it is the way going forward as far as the React Native project is concerned.
Navigator will also one day be deprecated and Navigation Experimental will be the main
Navigator as well as the one being maintained, so it is important to understand this API and
understand how to use it.
A basic concept to understand when working with NavigationExperimental is the idea of a
reducer function. A reducer is a function that takes in an initial state or value as an argument
and returns a new state or value based on all previous and current actions. Reducers must be
pure, meaning the reducer function should:
Something else to remember when writing reducers and working with the state of the
reducer is that the data structures should be immutable, meaning that we should not mutate
the state, but instead return a completely new data structure.
This means, for example, that instead of adding and removing items from an array stored
in the state when the time comes to update the array, we should create a copy of the array,
push or pop the item to or from the copied array, and then return the newly copied array
along with the existing state.
If you are new to the idea of immutable data, and you would like to have this idea
reinforced for you, there are a couple of open source projects that you can use in your
application. Check out ImmutableJS or Seamless Immutable as they are both great libraries
and are open source.
Let’s look at an example reducer function (listing 7.14).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
199
}
function personReducer(state = initialState, action) { ❷
switch(action.type) { ❸
case 'increment_age':
return { ❹
...state,
age: state.age + 1
}
case 'change_name':
return { ❺
...state,
name: action.name,
}
}
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
200
❶ navState is an object with at least two properties, an index and an array of routes
❷ renderScene is called when the navigationState is changed, and returns the route in the
navigationState routes array that corresponds with the current index of the navigationState
Again, renderScene will return the route in the navigationState routes array that
corresponds with the current index of the navigationState, therefore the following
navigationState will return the About route because the index is 2 and route in the
corresponding position in the routes array is 'About'(listing 7.17).
Now that we’ve gone over some of the basics, we can start building navigation using
NavigationExperimental.
To get started, we will create a basic app that will only render an initial route using
NavigationExperimental (listing 7.18, figure 7.4).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
201
const {
CardStack: NavigationCardStack, ❷
} = NavigationExperimental
let styles = {}
function reducer(state) { ❹
if (!state) {
return {
index: 0,
routes: [{key: 'Home'}],
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
202
};
}
}
_renderScene(props) { ❻
switch(props.scene.route.key) {
case 'Home':
return <Home />
}
}
render() {
const { navState } = this.state
return (
<NavigationCardStack ❼
navigationState={navState}
renderScene={this._renderScene}
/>
)
}
styles = {
container: {
justifyContent: 'center',
alignItems: 'center',
flex: 1
},
}
AppRegistry.registerComponent('App', () =>NavigationCardStackExample);
Now when we run this, we should just get the main Home route rendered to the scene as it is
the route that is in position 0 of the routes array in the navigationState object (figure 7.4).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
203
Now that we have the initial route set up, we can add in a navigate function along with
another route to navigate to and from, we will call this route About. We will also set up a
navigate method and update the reducer to take an action object (listing 7.19, figure 7.5).
const {
CardStack: NavigationCardStack,
} = NavigationExperimental
let styles = {}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
204
</View>
)
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
205
_navigate(action) { ❻
const navState = reducer(this.state.navState, action)
this.setState({
navState
})
}
render() {
const { navState } = this.state
return (
<NavigationCardStack
navigationState={navState}
renderScene={this._renderScene}
/>
)
}
}
styles = {
container: {
justifyContent: 'center',
alignItems: 'center',
flex: 1
},
}
AppRegistry.registerComponent('App', () =>NavigationCardStackExample);
❶ Home now takes a single prop, navigate, and we use navigate to move to the About route by calling navigate and
passing in a type of 'push', and a route object with a key of 'About'.
❷ About also takes the navigate method as a prop, and we use it to go back to the previous route by calling navigate
with the type of 'pop'
❸ the reducer function now takes an action, and we switch on the action type to either push or pop routes to our
navState. If push is called, we create a shallow copy of the routes array by calling .slice() on the routes array,
push the new route to the array, and then return a new object with the existing state, an index with a value of the
routes length minus 1, and the new routes array
❹ if pop is called, we call .slice on the route array, removing the last item in the array, and then return a new object
with the existing state, an index with a value of the routes length minus 1, and the new routes array
❺ renderScene now checks for the 'About' key and returns the About route if it matches
❻ the _navigate method calls the reducer method with the first argument being the navState, and the second
argument being the action, and resets the navState with the returned value of the reducer
Now, we should be able to press the ‘Go To About’ button and navigate to the About page.
Now that we have the basic navigation working, let’s add a header that will display the
current route title and a back button when not on the initial route.
To get started, we will need to import the Header component from NavigationExperimental
as well as create the header we will be using (listing 7.20, figure 7.6).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
206
const {
CardStack: NavigationCardStack,
Header: NavigationHeader, ❶
} = NavigationExperimental
let styles = {}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
207
return (
<NavigationHeader ❹
{...this.props}
renderTitleComponent={this._renderTitleComponent}
onNavigateBack={this._back}
/>
);
}
}
...
The next thing we need to do to is to return this new header component in our
NavigationCardStack component. To do this, NavigationCardStack has a method called
renderHeader that will return a Header component (listing 7.21).
❶ _renderHeader will return the new Header component we created earlier. We pass in the _navigate method
as well as all the props from the navigator.
❷ add renderHeader method as a prop to the NavigationCardStack component.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
208
If you are interested in further exploring the Navigation options available via open source
packages, I would especially take a close look at ExNavigation by Exponent, as the
maintainers work closely with the React Native team and are core contributors to React
Native.
7.4 Summary
• NavigatorIOS is a good basic navigator to begin using, but only works on iOS and may
not scale well to a large project.
• Navigator is currently the most stable navigation component. Navigator works cross
platform and there are a good amount of documentation and resources on the web for
this navigation implementation.
• The NavigationExperimental API is currently being finalized and is the next iteration of
navigation in the React Native project.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
209
8
Cross-platform APIs
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
210
Alert takes four arguments (listing 8.1). Alert.alert(title, message, buttons, options)
buttons array array of buttons, each being an object with two keys: title (string) and onPress
(function)
You can trigger an alert by calling the Alert.alert() method, passing in one or more arguments.
In our example, we will create an Alert with two options: ‘Cancel’ & ‘Show Message’. If
cancel is pressed, we will dismiss the Alert, and if Show Message is clicked, we will update the
state to show our message (listing 8.2)
render () {
const { showMessage } = this.state
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
211
return (
<View style={styles.container}>
<TouchableHighlight onPress={this.showAlert} style={styles.button}>
<Text>SHOW ALERT</Text>
</TouchableHighlight>
{ ❹
showMessage &&<Text>Showing message - success</Text>
}
</View>
)
}
}
styles = StyleSheet.create({
container: {
justifyContent: 'center',
flex: 1
},
button: {
height: 70,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#ededed'
}
})
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
212
8.1.2 AppState
AppState will tell you whether the app is active, inactive, or in the background. This will
basically call a method whenever the app state changes, allowing you to perform actions or
call other methods based on the state of the app. If you would like to log a user out for
example when they minimize the app, this would be where you would probably do so.
AppState will return either active, inactive or background when it is called. To set up this
method, you would add an eventlistener, and call a method when the event when it is fired.
The events that AppState uses to respond are either ‘change’, or ‘memorywarning’. We will
create an example using ‘change’ because it is what you will be mainly using in a real world
scenario.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
213
styles = StyleSheet.create({
container: {
justifyContent: 'center',
flex: 1
}
})
Now, when we run the project, we can test this by either pressing CMD + shift + H in iOS
simulator or pressing the home button in the Android emulator. We should not see the console
logging out the current app state (either active, inactive, or background).
8.1.3 AsyncStorage
Next up is the AsyncStorage API. AsyncStorage is a great way to persist and store data. It is
asynchronous, meaning that you can retrieve data either using a promise or async await, and
uses a key-value system to store and retrieve the data.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
214
mergeItem mergeItem(key, value, callback) merges existing value with another existing value.
(both values must be stringified JSON)
multiGet multiGet([keys], callback) allows you to get multiple values using an array
of keys
multiSet multiSet([keyValuePairs], callback) allows you to set multiple key value pairs at once.
multiMerge multiMerge([keyValuePars], callback) allows you to merge multiple key value pairs into
one method
In our example, we will take a user object and store it into the AsyncStorage in
componentDidMount. We will then use a button to extract the data from AsyncStorage,
populate our state with the data and render it to our View.
const person = { ❷
name: 'James Garfield',
age: 50,
occupation: 'President of the United States'
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
215
}
getPerson() { ❻
AsyncStorage.getItem(key)
.then((res) => this.setState({ person: JSON.parse(res) }))
.catch((err) => console.log('err: ', err))
}
render () {
const { person } = this.state
return (
<View style={styles.container}>
<Text style={{textAlign: 'center'}}>Testing AsyncStorage</Text>
<TouchableHighlight onPress={this.getPerson} style={styles.button}> ❼
<Text>Get President</Text>
</TouchableHighlight>
<Text>{person.name}</Text>
<Text>{person.age}</Text>
<Text>{person.occupation}</Text>
</View>
)
}
}
styles = StyleSheet.create({
container: {
justifyContent: 'center',
flex: 1,
margin: 20
},
button: {
justifyContent: 'center',
marginTop: 20,
marginBottom: 20,
alignItems: 'center',
height: 55,
backgroundColor: '#dddddd'
}
})
As you can see, we used promises to set and return the values from AsyncStorage. There’s
also another way to do this, so let’s take a look at async await.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
216
async await first requires you to mark the function as async by adding the async keyword
before the function name. We are then able to use the await keyword to wait for the,
allowingus to write promise-based code as if it were synchronous. When we await a promise,
the function waits until the promise settles, but does so in a non-blocking way, then assigns
the value to the variable.
8.1.4 ClipBoard
Clipboard lets you save and retrieve content from the clipboard on both iOS and Android.
ClipBoard has two methods (Listing 8.8).
In our example, we will set an initial Clipboard value of ‘Hello World’ in componentDidMount,
then use a method attached to the TextInput to update the clipboard, and add a button that
pushes the current ClipboardValue to an array, and renders it to our View.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
217
super()
this.state = {
clipboardData: [] ❷
}
this.pushClipboardToArray = this.pushClipboardToArray.bind(this)
}
componentDidMount () {
Clipboard.setString('Hello World! '); ❸
}
updateClipboard (string) {
Clipboard.setString(string); ❹
}
async pushClipboardToArray() { ❺
const { clipboardData } = this.state
var content = await Clipboard.getString();
clipboardData.push(content)
this.setState({clipboardData})
}
render () {
const { clipboardData } = this.state
return (
<View style={styles.container}>
<Text style={{textAlign: 'center'}}>Testing Clipboard</Text>
<TextInput style={styles.input} onChangeText={(text) =>
this.updateClipboard(text)} /> ❻
<TouchableHighlight onPress={this.pushClipboardToArray}
style={styles.button}> ❼
<Text>Click to Add to Array</Text>
</TouchableHighlight>
{
clipboardData.map((d, i) => { ❽
return <Text key={i}>{d}</Text>
})
}
</View>
)
}
}
styles = StyleSheet.create({
container: {
justifyContent: 'center',
flex: 1,
margin: 20
},
input: {
padding: 10,
marginTop: 15,
height: 60,
backgroundColor: '#dddddd'
},
button: {
backgroundColor: '#dddddd',
justifyContent: 'center',
alignItems: 'center',
height: 60,
marginTop: 15,
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
218
}
})
8.1.5 Dimensions
Dimensions gives us a way to get the device screen height and width. This is a good way to
set width and height in your device, or to do calculations that are based on the width and
height of the device.
To use Dimensions, you need to import the Dimensions api from React Native, then call the
get() method, and return either the width, the height, or both (listing 8.9).
styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
})
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
219
8.1.6 Geolocation
Geolocation is achieved in React Native using the same API that is used in the browser, with
the navigator.geolocation global variable. You do not need to import anything to begin using
this, as it is again available as a global.
To get started with geolocation, you must enable geolocation to be used in the app if
developing for Android (iOS is enabled by default) (listing 8.10).
watchPosition watchPosition (successcallback, will get the current position and will
errcallback, automatically be called when the device
optionsobject{enableHighAccuracy: position changes
Boolean, timeout: number, maximumAge:
number})
stopObserving none - stopObserving() will cancel the all geolocation watches that
have been set up
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
220
To see this in action, we will set up an instance of both geolocation getCurrentPosition and
watchPosition, and have a button that will enable us to clear the watch. We will then display
both the original coordinates as well as the updated coordinates (latitude and longitude)
(Listing 8.12).
Listing 8.8
import React, { Component } from 'react'
import { TouchableHighlight, View, Text, StyleSheet } from 'react-native'
let styles = {}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
221
}
render () {
const { originalCoords, updatedCoords } = this.state
return (
<View style={styles.container}> ❺
<Text>Original Coordinates</Text>
<Text>Latitude: {originalCoords.latitude}</Text>
<Text>Longitude: {originalCoords.longitude}</Text>
<Text>Updated Coordinates</Text>
<Text>Latitude: {updatedCoords.latitude}</Text>
<Text>Longitude: {updatedCoords.longitude}</Text>
<TouchableHighlight ❻
onPress={this.clearWatch}
style={styles.button}>
<Text>Clear Watch</Text>
</TouchableHighlight>
</View>
)
}
}
styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
button: {
height: 60,
marginTop: 15,
backgroundColor: '#ededed',
justifyContent: 'center',
alignItems: 'center'
}
})
❶ create an initial state with both an originalCoords and updatedCoords set as an empty object as well as id set as an
empty string
❷ in componentDidMount, call getCurrentPosition on navigator.geolocation and set the state of coriginalCoords to
success.coords
❸ call watchPosition and store the result of the function in a variable named id that we will use later to clear the
watch, and reset the state with the id.
❹ create clearWatch method to clear the watch that was created in step C
❺ in our render method, we display the latitude and longitude from both the original coordinates as well as the
updated coordinates
8.1.7 Keyboard
The Keyboard API allows us to have access to the native keyboard. We can use this to either
dismiss the keyboard, or to listen to keyboard events and call methods based on these events.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
222
Table 8.5
In our example, we will set up a TextInput and have listeners set up for all available events.
When the event is fired, we will log the event to the console. We will also have two buttons,
one to dismiss the keyboard and another to remove all event listeners that were set up in
componentWillMount (Listing 8.13).
let styles = {}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
223
Keyboard.removeAllListeners('keyboardWillHide')
Keyboard.removeAllListeners('keyboardDidHide')
Keyboard.removeAllListeners('keyboardWillChangeFrame')
Keyboard.removeAllListeners('keyboardDidChangeFrame')
}
render () {
return (
<View style={styles.container}>
<TextInput style={styles.input} />
<TouchableHighlight ❻
onPress={this.dismissKeyboard}
style={styles.button}>
<Text>Dismiss Keyboard</Text>
</TouchableHighlight>
<TouchableHighlight ❼
onPress={this.removeListeners}
style={styles.button}>
<Text>Remove Listeners</Text>
</TouchableHighlight>
</View>
)
}
}
styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 150,
},
input: {
margin: 10,
backgroundColor: '#ededed',
height: 50,
padding: 10
},
button: {
height: 50,
backgroundColor: '#dddddd',
margin: 10,
justifyContent: 'center',
alignItems: 'center'
}
})
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
224
8.1.8 NetInfo
NetInfo is an API that allows us to access data describing whether the device is online of
offline.
Both iOS and Android have different connectivity types (listing 8.14).
Table 8.6
iOS Android
none NONE
Wifi BLUETOOTH
cell DUMMY
unknown ETHERNET
MOBILE
MOBILE_DUN
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
225
MOBILE_HIPRI
MOBILE_MMS
MOBILE_SUPL
VPN
WIFI
WIMAX
UNKNOWN
To determine the connection, there are a few methods we can use (listing 8.15).
In our example, we will set up a NetInfo.fetch method to get the initial connection information,
and then set up a listener to log out the current NetInfo if and when it changes (Listing 8.16).
let styles = {}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
226
NetInfo.fetch().done((connection) => { ❸
console.log('connection: ' + connection)
this.setState({connection})
})
NetInfo.addEventListener('change', this.handleConnectivityChange) ❹
}
handleConnectivityChange (connection) { ❺
console.log('new connection:', connection)
this.setState({connection})
}
render () {
return (
<View style={styles.container}>
<Text>{this.state.connection}</Text> ❻
</View>
)
}
}
styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
})
8.1.9 PanResponder
PanResponder offers a way to make use of data from touch events. With it, we can granularly
respond to and manipulate our application state based on single and multiple touch events,
such as swiping, tapping, pinching, scrolling, and more.
For example, let’s take a look at a basic gesture event and see what type of data is
available to us using onPanResponderMove(event, gestureState), which gives us data about
the current position of the touch event, including current position, accumulated difference
between current position and original position among other things (listing 8.17).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
227
evt.nativeEvent
changedTouches Array of all touch events that have changed since the last event
timestamp A time identifier for the touch, useful for velocity calculation
Table 8.9
gestureState
stateID ID of the gestureState- persisted as long as there at least one touch on screen
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
228
For our example, we will create a draggable square, and will display the x and y coordinates of
the square to our view (Listing 8.20).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
229
let styles = {}
styles = StyleSheet.create({
container: {
flex: 1,
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
230
},
positionDisplay: {
textAlign: 'center',
marginTop: 50,
zIndex: 1,
position: 'absolute',
width
},
box: {
position: 'absolute',
width: 200,
height: 200,
backgroundColor: 'red'
}
})
❶ import Dimensions, PanResponder, and everything else we will be needing for this component
❷ store the window width and height in variables for later use
❸ create an object to store our original square position x and y axes to center the square, called oPosition, and store
into the state
❹ create an object to store our actual square position x and y axes to center the square, called position, and store into
the state
❺ create a new PanResponder, returning true for onStartShouldSetPanResponder, and setting up
onPanResponderMove and onPanResponderRelease methods
❻ in onPanResponderMove, we calculate the total movements of both x and y by calculating the difference between
the location of the panResponderGrant and the current total of movement since the grant. We then update the
state position with these values
❼ In handlePanResponderRelease, we set the state of oPosition with the updated position we are using in our view
❽ We display the current position values in our view
❾ We attach the created PanResponder to our view by passing in {...this._panResponder.panHandlers} as props
❿ We attach the position x and y values to our view to update the margins, making the item draggable
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
231
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
232
9
iOS-specific Components and
APIs
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
233
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
234
In listing 9.3, we import the Datepicker without giving a specific file extension. React Native
knows which component to import depending on the platform. From there, we are then able to
use it in our application without having to worry about which platform we are on.
In listing 9.4, we check to see if the value of Platform.OS is equal to the string 'ios', and if it
is, we return a color of blue. If it is not, we return green.
The second is a method called select. select takes in an object containing the
platform.OS strings as keys (either ios or android), and returns the value for the platform you
are running (listing 9.5).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
235
We can also use the ES2015 spread syntax to return objects, and use those objects to apply
styling (listing 9.6).
let styles = {}
styles = {
container: {
marginTop: 100,
...Platform.select({
ios: {
backgroundColor: 'red'
}
})
}
}
9.3 DatePickerIOS
DatePickerIOS provides an easy way to implement a native date picker component on iOS.
DatePickerIOS has three modes that come in handy when working with dates and times:
date, time, and dateTime.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
236
Figure 9.1 DatePicker with date mode, time mode, and datetime mode
The minimum props that need to be passed to the DatePickerIOS component are date (the
date that is the beginning or current date choice), and an onDateChange method.
When any of the date values are changed, onDateChange is called, passing the function the
new date value.
In our example, we will set up a DatePickerIOS component and display the time in the
View. We will not pass in a mode prop, as the mode defaults to datetime (Listing 9.7).
constructor() {
super()
this.state = {
date: new Date(), ❷
}
this.onDateChange = this.onDateChange.bind(this)
}
onDateChange(date) { ❸
this.setState({date: date});
};
render() {
return (
<View style={{ marginTop: 50 }}>
<DatePickerIOS ❹
date={this.state.date}
onDateChange={this.onDateChange}
/>
<Text style={{ marginTop: 40, textAlign: 'center' }}>
{ this.state.date.toLocaleDateString() } {
this.state.date.toLocaleTimeString() } ❺
</Text>
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
237
</View>)
}
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
238
9.4 PickerIOS
PickerIOS allows us to access the native IOS Picker component, which basically allows us to
scroll through and choose from a list of values using the Native UI.
PickerIOS wraps a list of items to be rendered as children. Each child item must be a
PickerIOS.Item.
import { PickerIOS } from ‘react-native’
const PickerItem = PickerIOS.Item
<PickerIOS>
<PickerItem />
<PickerItem />
<PickerItem />
</PickerIOS>
It is possible to declare each PickerIOS.Item individually as we have done above, but most of
the time you will be mapping over elements in an array and returning a PickerIOS.Item for
each item in the array (listing 9.8).
render() {
<PickerIOS>
{
people.map((p, i) =>(
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
239
<PickerItem />
))
}
</PickerIOS>
}
const people = [ ❷
{
name: 'Nader Dabit',
age: 36
},
{
name: 'Christina Jones',
age: 39
},
{
name: 'Amanda Nelson',
age: 22
}
];
constructor() {
super()
this.state = { ❸
value: 'Christina Jones'
}
this.onValueChange = this.onValueChange.bind(this)
}
onValueChange(value) { ❹
this.setState({ value });
};
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
240
render() {
return (
<View style={{ marginTop: 50 }}>
<PickerIOS ❺
onValueChange={this.onValueChange}
selectedValue={this.state.value}
>
{
people.map((p, i) => { ❻
return (
<PickerItem
key={i}
value={p.name}
label={p.name}
/>
)
})
}
</PickerIOS>
<Text style={{ marginTop: 40, textAlign: 'center' }}>
{this.state.value} ❼
</Text>
</View>)
}
}
onValueChange function(value) this method is called when the PickerIOS value changes
9.5 ProgressViewIOS
ProgressViewIOS is a way for us to render the native UIProgressView in our UI.
ProgressViewIOS basically is a native way for us to show loading percentage indication,
download percentage indication, or for any time we need to show an indication of a task that
is being completed.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
241
The main prop that we need to know about to create this functionality is the progress prop.
progress takes a number between 0 and 1 and fills the ProgressViewIOS with a percentage
fill between 0% and 100%.
In our example, we will simulate some data loading by setting a setInterval method that
gets called in componentDidMount, and increment the state value by 0.01 every 0.01 seconds
until we are at 1, starting the initial value at 0 (listing 9.10).
Listing 9.10
import React, { Component } from 'react'
import { Text, View, ProgressViewIOS } from 'react-native' ❶
constructor() {
super()
this.state = { ❷
progress: 0,
}
}
componentDidMount() {
this.interval = setInterval(() => { ❸
if (this.state.progress >= 1) {
return clearInterval(this.interval)
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
242
this.setState({
progress: this.state.progress + .01
})
}, 10)
}
render() {
return (
<View style={{ marginTop: 50 }}>
<ProgressViewIOS ❹
progress={this.state.progress}
/>
<Text style={{ marginTop: 10, textAlign: 'center' }}>
{Math.floor(this.state.progress * 100)}% complete ❺
</Text>
</View>)
}
}
progressTintColor string (color) the tint color of the progress bar itself
trackImage image source a stretchable image to display behind the progress bar
9.6 SegmentedControlIOS
SegmentedControlIOS allows us to access the native iOS UISegmentedControl component.
SegmentedControlIOS is basically a horizontal tab bar that is made up of individual buttons
(figure 9.5).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
243
Figure 9.5 Basic SegmentedControlIOS implementation with 2 values (one and two).
constructor() {
super()
this.state = {
selectedIndex: 0, ❸
}
}
render() {
const { selectedIndex } = this.state
let selectedItem = values[selectedIndex] ❹
return (
<View style={{ marginTop: 40, padding: 20 }}>
<SegmentedControlIOS ❺
values={values}
selectedIndex={this.state.selectedIndex}
onChange={(event) => {
this.setState({selectedIndex: event.nativeEvent.selectedSegmentIndex});
}}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
244
/>
<Text>{selectedItem}</Text> ❻
</View>)
}
}
enabled Boolean If false the user won't be able to interact with the control. Default value is true.
momentary Boolean if true, then selecting a segment won't persist visually. The onValueChange
callback will still work as expected.
onChange function (event) Callback that is called when the user taps a segment; passes the event as an
argument
onValueChange function (value) Callback that is called when the user taps a segment; passes the segment's
value as an argument
values array of strings The labels for the control's segment buttons, in order.
9.7 TabBarIOS
TabBarIOS allows us to access the native iOS Tab Bar. TabBarIOS renders tabs at the bottom
of the UI, allowing a nice and easy way to separate your application into sections.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
245
<TabBarIOS>
<Item>
<View> // some content here </View>
</Item>
<Item>
<View> // some other content here </View>
</Item>=
</TabBarIOS>
To show the content within the TabBarIOS.Item, the selected prop of the TabBarIOS.Item
must be true.
<Item
selected={this.state.selectedComponent === 'home'}
>
// your content here
</Item>
In our example, we will create an app with two views: History and Favorites. When the
TabBarIOS.Item is clicked, we will switch between views by calling an onPress method to
update the state (Listing 9.12).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
246
constructor() {
super()
this.state = {
selectedTab: 'history', ❸
}
this.renderView = this.renderView.bind(this)
}
renderView(tab) { ❹
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Hello from {tab}</Text>
</View>
)
}
render() {
return (
<TabBarIOS> ❺
<Item
systemIcon="history" ❻
onPress={() => this.setState({ selectedTab: 'history' })} ❼
selected={this.state.selectedTab === 'history'}
>
{this.renderView('History')} ❽
</Item>
<Item
systemIcon='favorites'
onPress={() => this.setState({ selectedTab: 'favorites' })}
selected={this.state.selectedTab === 'favorites'}
>
{this.renderView('Favorites')}
</Item>
</TabBarIOS>
)
}
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
247
itemPositioning enum('fill', 'center', 'auto') Specifies tab bar item positioning. Available values are: - fill
- distributes items across the entire width of the tab bar -
center - centers item in the available tab bar space - auto
(default) - distributes items dynamically according to the
user interface idiom. In a horizontally compact environment
(e.g. iPhone 5) this value defaults to fill, in a horizontally
regular one (e.g. iPad) it defaults to center.
translucent Boolean A Boolean value that indicates whether the tab bar is
translucent
unselectedItemTintColor string (color) Color of unselected tab icons. Available since iOS 10.
9.8 ActionSheetIOS
ActionSheetIOS allows us to access the native iOS UIAlertController to show a native iOS
action sheet or share sheet.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
248
Listing 9.7 ActionSheetIOS rendering an action sheet (left) and a share sheet (right)
In our example, we will create a View with two buttons. One button will call
showActionSheetWithOptions and the other will call
showShareActionSheetWithOptions(listing 9.13).
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
249
Listing 9.13 Using ActionSheetIOS to create action sheets and share sheets.
import React, { Component } from 'react'
import {Text, View, ActionSheetIOS, TouchableHighlight } from 'react-native' ❶
showActionSheet() { ❹
ActionSheetIOS.showActionSheetWithOptions({
options: BUTTONS,
cancelButtonIndex: 0,
},
(buttonIndex) => {
if (buttonIndex > 0) {
this.setState({ clicked: BUTTONS[buttonIndex] });
}
});
}
showShareActionSheetWithOptions() { ❺
ActionSheetIOS.showShareActionSheetWithOptions({
url: 'http://www.reactnative.training',
message: 'React Native Training',
},
(error) => console.log('error:', error),
(success, method) => {
if (success) {
console.log('successfully shared!', success)
}
});
};
render() {
return (
<View style={styles.container}> ❻
<TouchableHighlight onPress={this.showActionSheet} style={styles.button}>
<Text style={styles.buttonText}>Show ActionSheet</Text>
</TouchableHighlight>
<TouchableHighlight onPress={this.showShareActionSheetWithOptions}
style={styles.button}>
<Text style={styles.buttonText}>Show ActionSheet With Options</Text>
</TouchableHighlight>
<Text>
{this.state.clicked}
</Text>
</View>
)
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
250
}
}
styles = {
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
button: {
height: 50,
marginBottom: 20,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'blue'
},
buttonText: {
color: 'white'
}
}
❻ create two buttons in our View, and attach the showActionSheet and
showShareActionSheetWithOptions to them
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
251
9.9 Summary
• Using platform android.js and ios.js extensions to import cross-platform files
• Using the Platform API to render platform specific code
• Implementing DatePickerIOS to choose and save dates in your app
• Using PickerIOS to render and save values from a list
• Using ProgressViewIOS to show loading progress
• Using SegmentedControlIOS to choose from an array of options
• Using TabBarIOS to create and switch between tabs in your app
• How ActionSheetIOS allows us to call either a native iOS action sheet or share sheet in
an app
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
252
A
Installing and running
React Native
NOTE If you do not have homebrew installed, go to http://brew.sh/ and install homebrew before following
the next steps.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
253
4. React Native command line interface – this should be installed via the command line
Next, we will check to see if we have React Native properly installed by creating a new project.
In the terminal or on your command line of choice, run the following commands:
react-native init MyProject
cd MyProject
Now that we’ve created the new project and changed into the new directory, we can run the
project in a couple of different ways.
• Run the project from the command line: To do this, execute react-native run-ios
from within the MyProject directory.
• Open the project in Xcode: To do this, open the MyApp.xcodeproj file located at
MyProject/ios/MyApp.xcodeproj .
• Node.js
• React Native command line tools
• Watchman
• Android Studio
The React Native docs, as well as myself, recommend installing node and watchman via
homebrew.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
254
3. Once node.js is installed, then install the React Native command line tools by running
the following command from your command line:
Once everything is installed, go to section A.3 of the appendix to create your first project.
• node.js
• React Native command line tools
• Watchman
• Android Studio
Watchman is in the alpha stage for Windows, but is working fine so far in my experience.
Once everything is installed, go to section A.3 of the appendix to create your first project.
• Node.js
• React Native command line tools
• Watchman
• Android Studio
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action
Licensed to Zeehsan Hanif <zee81zee@yahoo.com>
255
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/react-native-in-action