Tracking Time Spent in React Native
Accurate tracking of the time spent by a user in react native mobile application
What do we want to do?
We want to track the time spent by the user across our application. To give a bit of context, we use react-native for developing our mobile application. We embody the DRY (Don’t Repeat Yourself) principle to reduce code duplication. So, we have decided to write a HOC (Higher Order Component) in our application to track user activity across multiple components. Simply put, the following are the OKRs:
Objective:
To accurately measure the time spent by the user undertaking a task.
Key Results:
- Measure the time spent by the User.
- Discard the time when the user is idle on the app.
- Discard the time when the app is in the background
How did we do it?
We did this by writing a HOC component named Timer
that can be used to wrap other components for which time tracking is required. HOC is a technique in React for reusing component logic i.e. HOC takes a component as an argument and returns a new component.
Measure the time spent by the user
To measure the time spent, we have added resetTimer
and stopTimer
methods as props to the Wrapped Component. The render method will look as follows:
Here we use the resetTimer
method to start theActivityTimer
which is used to increment the activeSeconds
(state object) using setInterval
Following are the code snippets
Discard the time when the user is idle on the app
To discard the time when the user is idle on the app i.e. when the app is open but there is no activity, we have added one more timer called InactivityTimer
which is doing the countdown of seconds starting from the specifiedinactiveSeconds
which is passed as an argument to this HOC. This is used to stop the timer when the user is idle for a certain number of seconds. The following is the updated code snippet to perform the mentioned operations.
As shown above, we are calling thestopTimer
method when the inactiveSeconds
reaches zero.
Here we will be calling the resetTimer
method in the wrapped component to start the timer. One way to do this is to call the resetTimer
method in getDerivedStateFromProps
which is invoked right before calling the render method. Here the resetTimer
method is used to reset the inactiveSeconds
timer. One challenge we encountered here is tracking the touches of the user so that we can reset the inactiveSeconds
timer on touch. Since touches won’t affect the state (or) props of the component, getDerivedStateFromProps
cannot be used. So, we made use of UserInactivity from react-native-user-inactivity
library which is used around the wrapper component to track user touches. Here we added includeTouchActivity
as a parameter to our HOC to make this feature customizable. Following is the code snippet:
Discard the time when the app is in the background
To discard the time spent when the app is in the background i.e. to stop the timer, we made use of AppState
from react-native
which can tell you if the app is in the foreground or background, and notify you when the state changes. So, we are calling stopTimer
method when the app goes to background and resetTimer
method when the app comes to the foreground. Following are the updated code snippets.
Conclusion
Your HOC is ready now and we have achieved all our key results to accurately measure time spent by the user on any page of the mobile application.