How to build a background timer in Expo/React Native

Photo by Djim Loic on Unsplash

Insight #1: use AsyncStorage to store starting time

const recordStartTime = async () => {
try {
const now = new Date();
await AsyncStorage.setItem("@start_time", now.toISOString());
} catch (err) {
// TODO: handle errors from setItem properly
console.warn(err);
}
};

Insight #2: use AppState to adjust timer

import { useEffect } from "react";
import { AppState } from "react-native"
import AsyncStorage from "@react-native-community/async-storage";
import { differenceInSeconds } from "date-fns";
const appState = useRef(AppState.currentState);
const [elapsed, setElapsed] = useState(0);
useEffect(() => {
AppState.addEventListener("change", handleAppStateChange);
return () => AppState.removeEventListener("change", handleAppStateChange);
}, []);
const handleAppStateChange = async (nextAppState) => {
if (appState.current.match(/inactive|background/) &&
nextAppState === "active") {
// We just became active again: recalculate elapsed time based
// on what we stored in AsyncStorage when we started.
const elapsed = await getElapsedTime();
// Update the elapsed seconds state
setElapsed(elapsed);
}
appState.current = nextAppState;
};
const getElapsedTime = async () => {
try {
const startTime = await AsyncStorage.getItem("@start_time");
const now = new Date();
return differenceInSeconds(now, Date.parse(startTime));
} catch (err) {
// TODO: handle errors from setItem properly
console.warn(err);
}
};

Warning: a background task this is not

--

--

--

Co-founder & CTO @ AgentRisk. Former infra-tech guy (storage, networks). Startup nerd. Always building cool side-projects. #LongLA

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Simplifying Regular expressions in javascript.

2WDScroll — jQuery plugin for implementing Double Scrollbars

TIL/2020–12–25

Introduction to React Hooks

Testing React Apps with Jest and chai-enzyme for Beginners

React Tutorial — Learn React in 5 hours

Build a carousel with react-spring-carousel-js

removeDuplicates: For every sequence of consecutive identical items in a, retain only one item of…

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alex Loukissas

Alex Loukissas

Co-founder & CTO @ AgentRisk. Former infra-tech guy (storage, networks). Startup nerd. Always building cool side-projects. #LongLA

More from Medium

Introducing ACRN: An Accessibility Component Library for React Native

Switch between project build variants (staging, production, etc) in React Native — part 1

Accessibility in React Native Apps

Developer with their smartphone and laptop

Animations In Practice 2 — React Native Gesture-based Animations