Creating a Mobile Application with Reapp
Why React ?
React works on the concept of the “virtual DOM” which makes it different to other JS libraries. When a change occurs it updates the virtual DOM instead of updating the actual DOM. When there are a couple of changes in the virtual DOM, it makes a single update thus avoiding frequent updates to DOM.
From the official site,
React abstracts away the DOM from you, giving a simpler programming model and better performance. React can also render on the server using Node, and it can power native apps using React Native.
Introducing Reapp.io
Reapp is a platform to create mobile apps. It provides a UI kit of components, optimized and fully customizable for creating mobile apps.
What we’ll create
In this tutorial, we’ll learn how to create a mobile app using Reapp. We’ll call this app, the “Where was I” app. The app will help a user save different locations. We’ll make use of the Google Maps API to enable users to select locations. We’ll use Firebase as the back end to save data.
Source code for this tutorial is available on GitHub.
Get Started
We’ll start by installing reapp
and create a project called ReactApp
.
1
2
|
npm install -g reapp reapp new ReactApp |
Open the project directory, run reapp and the app should be running at http://localhost:3010.
1
|
cd ReactApp && reapp run |
Here is the resulting project structure.
Inside the project directory is the app folder which contains the app.js file. Different routes for the application are defined in the app.js file. The components folder contains the different components that would be rendered when a particular route is requested.
Creating Views
Start by removing the sub.jsx file from the components/home folder. Open home.jsx and remove the existing code Let’s start from scratch and try to understand how things work. We’ll create a react class called Home
to render our component.
1
2
3
4
5
6
7
8
9
10
11
|
import { Reapp, React, View} from 'reapp-kit' ; var Home = React.createClass({ render: function () { return ( <h2>Welcome to Reapp!!</h2> ); } }); export default Reapp(Home); |
As seen above, the render function returns the view to be displayed. Update the routes in the app.js file.
1
2
3
4
5
6
|
import './theme' ; import { router, route } from 'reapp-kit' ; router(require, route( 'home' , '/' ) ); |
Save changes and restart the server. Open http://localhost:3010 in your browser and you should see the default view. I would recommend enabling device emulation in chrome developer tools to view the app as a mobile app.
Next we’ll integrate Google Maps into our view. Add a header for the app by modifying home.jsx to return a view inside the render function.
1
2
3
|
< View title = "Where Am I" > </ View > |
Next create a new map component to display Google maps. Start by adding the google maps API reference in the assets/web/index.html
page.
1
|
|
In home.jsx
create a new React component which will display the Google Map.
1
2
3
4
5
6
7
8
|
var MapView = React.createClass({ render: function () { return ( <div id= "map" ><span>Map Would be Here !!</span></div> ); } }); |
Add the MapView
component to the home view.
1
2
3
4
5
|
< View title = "Where Am I" > < MapView /> < MapView /> </ View > |
Add the following style to assets/web/index.html.
1
2
3
4
5
6
7
8
|
<style> #map { width : 100% ; height : 400px ; margin : 0px ; padding : 0px ; } </style> |
Save changes and restart the server. You should see the text Map Would be here !!
on your app screen.
Adding Google Maps
We have seen how to nest react components. Next we’ll remove the span
inside the MapView
render function and replace it with the actual map. Once the component has been mounted we’ll create the Google Map and render it in the #map
div.
We’ll write our Google Maps code in the componentWillMount
lifecycle method. Inside the MapView
component add the componentWillMount
method.
1
2
3
|
componentDidMount: function () { // Code will be here }, |
Inside componentDidMount
define a default map location, map options and create the map.
1
2
3
4
5
6
7
8
9
10
11
|
var sitepoint = new google.maps.LatLng(-37.805723, 144.985360); var mapOptions = { zoom: 3, center: sitepoint }, map = new google.maps.Map(React.findDOMNode( this ), mapOptions); this .setState({ map: map }); |
In the code above React.findDomNode
gets a reference to the component’s DOM node element andsetState
triggers UI updates. Save changes and restart the server. If all is well, you should be able to view the map.
Let’s add a marker to our Google Maps. We’ll set several options to our marker such as animation
anddraggable
.
1
2
3
4
5
6
|
marker = new google.maps.Marker({ map:map, draggable: true , animation: google.maps.Animation.DROP, position: sitepoint }); |
Here is the full MapView
component:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
var MapView = React.createClass({ componentDidMount: function () { var sitepoint = new google.maps.LatLng(-37.805723, 144.985360); var mapOptions = { zoom: 3, center: sitepoint }, map = new google.maps.Map(React.findDOMNode( this ), mapOptions), marker = new google.maps.Marker({ map:map, draggable: true , animation: google.maps.Animation.DROP, position: sitepoint }); this .setState({ map: map }); }, render: function () { return ( <div id= "map" ><span>Map Would be Here !!</span></div> ); } }); |
Save changes, restart the server and you should have the map with a marker.
Adding Position Info
When the user drags the marker the position info should show. To implement this, add the required HTML in the Home
component. Modify the render function code to look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
render: function () { return ( <View title= "Where Am I" > <MapView /> <div style={{width:100 + '%' ,height:100 + 'px' ,margin: 0 + ' auto' ,padding:10 + 'px' }} id= "infoPanel" > <div> <span><b>Position:</b></span> <span id= "info" ></span> </div> <div> <span><b>Address:</b></span> <span id= "address" ></span> </div> </div> </View> ); } |
Set the default position and address. For the position, as the default latitude and longitude is hard-coded, set the info value as shown:
1
|
document.getElementById( 'info' ).innerHTML = '-37.805723, 144.985360' ; |
To display the address we’ll make use of Google Maps Geocoder.
1
2
3
4
5
6
7
|
geocoder.geocode({ latLng: marker.getPosition() }, function (responses) { if (responses && responses.length > 0) { document.getElementById( 'address' ).innerHTML = responses[0].formatted_address; } }); |
Here is the modified MapView
component:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
var MapView = React.createClass({ componentDidMount: function () { var geocoder = new google.maps.Geocoder(); var sitepoint = new google.maps.LatLng(-37.805723, 144.985360); document.getElementById( 'info' ).innerHTML = '-37.805723, 144.985360' ; var mapOptions = { zoom: 3, center: sitepoint }, map = new google.maps.Map(React.findDOMNode( this ), mapOptions), marker = new google.maps.Marker({ map:map, draggable: true , animation: google.maps.Animation.DROP, position: sitepoint }); geocoder.geocode({ latLng: marker.getPosition() }, function (responses) { if (responses && responses.length > 0) { document.getElementById( 'address' ).innerHTML = responses[0].formatted_address; } }); this .setState({ map: map }); }, render: function () { return ( <div id= "map" ><span>Map Would be Here !!</span></div> ); } }); |
Save changes, restart the server and you should have the default position and address displayed in the app.
Let’s add a dragend
event listener to update the position and address once the marker is dragged. Inside the dragend
callback function the marker position and address will be fetched and the address
andinfo
elementsupdated with the values.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
google.maps.event.addListener(marker, 'dragend' , function (e) { var obj = marker.getPosition(); document.getElementById( 'info' ).innerHTML = e.latLng; map.panTo(marker.getPosition()); geocoder.geocode({ latLng: obj }, function (responses) { if (responses && responses.length > 0) { document.getElementById( 'address' ).innerHTML = responses[0].formatted_address; } }); }); |
Save changes and restart the server. Now if the marker is dragged, the info is updated when dragging ends.
Save Information in Firebase
Let’s add a button to save the coordinates in Firebase. First install reapp-ui
into the project.
1
|
npm install reapp-ui@0.12.47 |
Import the button component into Home.jsx.
1
|
import Button from 'reapp-ui/components/Button' ; |
Add the button to the Home component.
1
|
< Button onTap={this.savePosition}>Save </ Button > |
On tapping the Save
button a function will save the coordinates to Firebase. Register for a free account on Firebase to use it in this app. Once registered you should have a Firebase URL to start working. Here is my Firebase URL:
1
|
https: //blistering-heat-2473 .firebaseio.com |
Login to your firebase account and click on the plus icon on the Firebase URL displayed in your dashboard to create a URL such as:
1
|
https: //blistering-heat-2473 .firebaseio.com /Position |
Use the above URL to save the location information.
Include a reference to Firebase in the assets/web/index.html
page.
1
|
|
Next, define the savePosition
function in the Home
component which will be called on tapping the save button.
1
2
3
4
5
6
7
8
9
10
|
savePosition: function () { var pos = document.getElementById( 'info' ).innerHTML; var address = document.getElementById( 'address' ).innerHTML; wishRef.push({ 'Position' : pos, 'Address' : address }); }, |
As seen above, we created a Firebase object using the Firebase URL and pushed the data to Firebase using the push API function.
Save changes and restart the server. Locate a position on the map and click save. Check firebase and the data should be saved.
Let’s add an alert to notify the user that the data has been saved. We’ll make use of the modal component, so import modal into Home.jsx.
1
|
import Modal from 'reapp-ui/components/Modal' ; |
Inside the Home View component’s render function, add the following modal code above
1
2
3
4
5
6
|
{ this .state.modal && <Modal title= "Coordinates Saved." onClose={() => this .setState({ modal: false })}> </Modal> } |
This will be visible when the state.modal
is true. Initialize state.modal
to false when the app loads. For that make use of the getInitialState
method. Inside the Home
component define thegetInitialState
.
1
2
3
4
5
|
getInitialState: function () { return { modal: false }; } |
Inside the savePosition
method after pushing the data to firebase, set the state.modal
to true to show the modal.
1
|
this .setState({ modal: true }); |
Save changes and restart the server. Once the app has loaded, click on the Save
button to save the data and you should be able to see the modal pop up.
Conclusion
In this tutorial, we saw how to get started with creating a mobile app using ReactJS, Reapp and Firebase. We created an app to save the map coordinates selected in the Google Maps to Firebase.
I hope this tutorial serves as starting point for creating mobile apps using ReactJS. Let me know your thoughts regarding React and Reapp and how you think they compare to existing JavaScript frameworks.