Creating a Mobile Application with Reapp
This post was updated in May 2016 to reflect changes in React and Reapp.
React is a JavaScript library focused on building user interfaces. It’s increase in popularity has been helped in part by the fact that it’s created, used and maintained by Facebook.
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 changes in the virtual DOM, it makes a single update, 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 customizable for creating mobile apps.
What You’ll Create
In this tutorial, you’ll learn how to create a mobile app using Reapp. The app will help a user save different locations, making use of the Google Maps API. It will use Firebase as a back end to save data.
Source code for this tutorial is available on GitHub.
Getting Started
Start by installing reapp
and create a project called ReactApp.
npm install -g reapp
reapp new ReactApp
Open the project directory, run reapp and the app should be running at http://localhost:3010.
cd ReactApp && reapp run
Here is the resulting project structure.
Inside the project directory is the app folder which contains the app.js file. The app.js file defines different routes for the application. The components folder contains the different components rendered when requesting a particular route.
Creating Views
Start by removing the sub.jsx file from the components/home folder. Open home.jsx and remove the existing code to start from scratch and understand how things work. You’ll create a react class called Home
to render the component.
import { Reapp, React, View} from 'reapp-kit';
var Home = React.createClass({
render: function() {
return (
<h1>Welcome to Reapp!!</h1>
);
}
});
export default Reapp(Home);
The render function returns the view to be displayed. Next update the routes in the app.js file.
import './theme';
import { router, route } from 'reapp-kit';
router(require,
route('home', '/')
);
Save the changes and restart the server. Open http://localhost:3010 in your browser and you should see the default view. I recommend enabling device emulation in chrome developer tools to view the app as a mobile app.
Next you’ll integrate Google Maps into the view. Add a header for the app by modifying home.jsx to return a view inside the render function.
<View title="Where Am I">
</View>
Create a new map component to display Google maps by adding a google maps API reference to the assets/web/index.html page.
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
In home.jsx, create a new React component which will display the Google Map.
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.
<View title="Where Am I">
<MapView />
</View>
Add the following style to assets/web/index.html.
<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
You have seen how to nest react components, so next you’ll remove the span
inside the MapView
render function and replace it with the actual map. Once the component has mounted it will create the Google Map and render it in the #map
div.
You’ll write the Google Maps code in the componentWillMount
lifecycle method. Inside the MapView
component add the componentWillMount
method.
componentDidMount: function() {
// Code will be here
},
Inside componentDidMount
define a default map location, map options and create the map.
var sitepoint = new google.maps.LatLng(-37.805723, 144.985360);
var mapOptions = {
zoom: 3,
center: sitepoint
},
map = new google.maps.Map(ReactDOM.findDOMNode(this), mapOptions);
this.setState({
map: map
});
To use ReactDOM.findDOMNode
you will need to require react-dom
, so add this after the opening import
statement.
var ReactDOM = require('react-dom')
In this code, ReactDOM.findDOMNode
gets a reference to the component’s DOM node element and setState
triggers UI updates. Save the changes and restart the server. If all is well, you should be able to view the map.
Now to add a marker to the Google Map. You’ll set several options to the marker such as animation
and draggable
.
marker = new google.maps.Marker({
map:map,
draggable:true,
animation: google.maps.Animation.DROP,
position: sitepoint
});
Here is the full MapView
component:
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(ReactDOM.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 a 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. Change the render function code to look like this:
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>
);
}
Next you need to hard-code the default position (latitude and longitude) and address. Add this line after initializing the sitepoint
variable in the componentDidMount
method:
document.getElementById('info').innerHTML = '-37.805723, 144.985360';
To display the address you’ll use the Google Maps Geocoder.
geocoder.geocode({
latLng: marker.getPosition()
}, function(responses) {
if (responses && responses.length > 0) {
document.getElementById('address').innerHTML = responses[0].formatted_address;
}
});
Here is the current MapView
component:
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(ReactDOM.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 the changes, restart the server and you should have the default position and address displayed in the app.
Now 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 are fetched and the address
and info
elements updated with the values.
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 the changes and restart the server. Now when dragging the marker, the info updates when dragging ends.
Save Information to Firebase
Next add a button to save the coordinates to Firebase. First add reapp-ui
to the project.
npm install reapp-ui@0.12.47
Import the button component into Home.jsx.
import Button from 'reapp-ui/components/Button';
Add the button to the Home component, at the bottom of the <View>
component. On tapping the Save
button a function will save the coordinates to Firebase.
<Button onTap={this.savePosition}>Save </Button>
Register for a free account with Firebase to use the service in this app. Once registered you should have a Firebase URL to use, here is my Firebase URL:
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:
https://blistering-heat-2473.firebaseio.com/Position
And use this URL to save the location information.
Include a reference to Firebase in the assets/web/index.html page.
<script src="https://cdn.firebase.com/js/client/2.0.4/firebase.js"></script>
Next, define the savePosition
function in the Home
component, called when tapping the save button.
savePosition: function() {
var wishRef = new Firebase('https://blistering-heat-2473.firebaseio.com/Position');
var pos = document.getElementById('info').innerHTML;
var address = document.getElementById('address').innerHTML;
wishRef.push({
'Position': pos,
'Address': address
});
},
This creates a Firebase object using the Firebase URL and pushes the data to Firebase using the push API function.
Save the 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. This wil use the modal component, so import modal into Home.jsx.
import Modal from 'reapp-ui/components/Modal';
Inside the Home View component’s render function, add the following modal code above <MapView />
{this.state.modal &&
<Modal
title="Coordinates Saved."
onClose={() => this.setState({ modal: false })}>
</Modal>
}
This will be visible when the state.modal
is true, so initialize state.modal
to false when the app loads using the getInitialState
method. Inside the Home
component define the getInitialState
.
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.
this.setState({ modal: true });
Save the changes and restart the server. Once the app has loaded, click on the Save button to save the data and you should see the modal pop up.
Conclusion
In this tutorial, you learnt how to create a mobile app using ReactJS, Reapp and Firebase. You created an app to save the map coordinates selected on a Google Map to Firebase.
I hope this tutorial serves as a good starting point for creating mobile apps using ReactJS. Let me know your thoughts and experiences using React and Reapp and how you think they compare to other mobile JavaScript frameworks.