Using Higher Order Components (HOC) and Capacitor Geolocation in an Ionic React application
In the previous tutorial, we have seen a new concept brought by React: the Higher Order Components (HOC).
In this tutorial, we will see a more practical example by using the Capacitor Geolocation plugin in an Ionic React application that will display the user's current location.
Don't forget to head there if you need to know how to couple React with Ionic.
Since we will use the Capacitor Geolocation plugin, we need to go through some installations:
npm install --save @capacitor/cli @capacitor/core
Let's refresh our memory, we already have the main.jsx file that renders a SimpleReactComponent:
import React, { Component } from "react";
import ReactDOM from "react-dom";
import SimpleReactComponent from "./app/SimpleReactComponent.jsx";
ReactDOM.render(
<SimpleReactComponent/>
,document.getElementById("root")
);
The SimpleReactComponent looks like this:
import React from 'react';
const Component = props => {
return (
<div>
Just a React Component
</div>
);
};
export default Component;
We will use this React Component to display the position by using the following HOC named withGeolocation:
import React from 'react';
import { Plugins } from '@capacitor/core';
const { Geolocation } = Plugins;
export default function withGeolocation(OriginalComponent) {
class HOC extends React.Component {
constructor() {
super();
this.state = { coords: null };
}
componentDidMount() {
Geolocation.watchPosition({}, (position, err) => {
if (!err) {
this.setState({coords: position.coords});
}
})
}
render() {
return <OriginalComponent {...this.props} coords={this.state.coords} />;
}
}
return HOC;
}
As we did in the previous tutorial, we create our HOC that will use an OriginalComponent (in our example this will be the SimpleReactComponent) with its default props.
This is where the whole Geolocation process is done.
We acquire the Geolocation Service located in the Capacitor Plugins from the '@capacitor/core' library.
Then we initialise the state of the Component in the constructor with some empty coords properties.
Once the componentDidMount hook is triggered, the watchPosition from Geolocation is used to get the current position and if everything is good, we update the React Component's state with the new coords.
At the end, we render the OriginalComponent and pass it the coords props with the value we currently have in our state.
We only need to update our SimpleReactComponent like this:
import React, { Component } from 'react';
import withGeolocation from './withGeolocation/withGeolocation.jsx';
class SimpleReactComponent extends Component {
constructor(props) {
super(props);
}
render() {
if(this.props.coords) {
return `Latitude: ${this.props.coords.latitude},
Longitude: ${this.props.coords.longitude}`;
} else {
return "No Geolocation data";
}
}
}
export default withGeolocation(SimpleReactComponent);
We import the newly created withGeolocation method.
Then we transform our Component into a React Component because it's easier to work with in our case.
The render method is a bit more sophisticated now.
Geolocation information usually takes time to initialise so we will do some conditional rendering.
If the props contains the coords, we can display the information.
If it's not ready, we display a message saying that there are no data.
Finally, instead of returning the SimpleReactComponent like we did before, we have to return the result of the withGeolocation method, which is an augmented version (with the coords props) of the SimpleReactComponent.
And Voila!
We have the latitude and longitude printed on screen: