React-Native consume user’s location with redux-saga
Consume the user's location using the navigation
API, and open a channel to emit the position changes.
Intro
The following snippet uses React-Native geolocation
.
From their documentation: "As a browser polyfill, this API is available through the navigator.geolocation global - you do not need to import it."
You may want to read about redux-saga's channels.
Define the actions
This script contains the action that will be logged when the user's location changes.
// ../Actions/Location.js
import { createAction } from 'redux-actions'
export const LOCATION_CHANGE = 'LOCATION_CHANGE'
export const constants = {
LOCATION_CHANGE
}
export const change = createAction(LOCATION_CHANGE)
Create a Saga's channel
This script will be consuming the user location and emitting events in a saga's event-channel.
// ../Services/Location.js
import { eventChannel, END } from 'redux-saga'
const { watchPosition } = navigator.geolocation
// Configuration for the `geolocation.watchPosition`.
const WATCH_POSITION_OPTIONS = {
enableHighAccuracy: true,
timeout: 20000,
maximumAge: 1000,
distanceFilter: 10
}
// Define the function to open the location listener.
export function locationChangeChannel () {
// Return the event channel.
return eventChannel((emit) => {
// Close the channel after any errors in `watchPosition`.
const onError = (error) => emit(END)
// Invokes the `emit` callback whenever the location changes.
const watchId = watchPosition(emit, onError, WATCH_POSITION_OPTIONS)
// The `eventChannel` call should return the unsubscribe
// function, this will stop watching of the location of the user.
return () => navigator.geolocation.clearWatch(watchId)
})
}
export default locationChangeChannel
Consume the channel in a Saga.
This is the script that will consume the events from the eventChannel
and log the LOCATION_CHANGE
action.
// ../Sagas/Location.js
import { all, call, put, takeEvery } from 'redux-saga/effects'
import { change } from '../Actions/Location'
import { locationChangeChannel } from '../Services/Location'
function * locationChange ({ coords }) {
// The `latitude`, `longitude`
// parameters come from `watchPosition`.
const { latitude, longitude } = coords
// Log the `LOCATION_CHANGE` action.
yield put(change({ latitude, longitude }))
}
function * openLocationWatch () {
const channel = yield call(locationChangeChannel)
yield takeEvery(channel, locationChange)
}
export default function * LocationSagas () {
yield all([
openLocationWatch()
])
}
Subscribe to RECodes
Get the latest posts delivered right to your inbox